From 6fb6b93003a40608c5326b3b9a79576c2bafd3a8 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Tue, 5 Jul 2016 21:33:22 +0200 Subject: [PATCH 1/8] speedup base --- atom/app/atom_main_delegate.cc | 393 +++++++++-------- atom/app/atom_main_delegate.h | 132 +++--- atom/browser/api/frame_subscriber.cc | 47 +- atom/browser/api/frame_subscriber.h | 17 + atom/browser/native_window_views.cc | 24 ++ atom/browser/native_window_views.h | 1 + atom/browser/osr_window.cc | 623 +++++++++++++++++++++++++++ atom/browser/osr_window.h | 206 +++++++++ default_app/default_app.js | 5 + filenames.gypi | 2 + 10 files changed, 1212 insertions(+), 238 deletions(-) create mode 100644 atom/browser/osr_window.cc create mode 100644 atom/browser/osr_window.h diff --git a/atom/app/atom_main_delegate.cc b/atom/app/atom_main_delegate.cc index f4e0b60444..891cdd3056 100644 --- a/atom/app/atom_main_delegate.cc +++ b/atom/app/atom_main_delegate.cc @@ -1,177 +1,216 @@ -// Copyright (c) 2013 GitHub, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#include "atom/app/atom_main_delegate.h" - -#include -#include - -#include "atom/app/atom_content_client.h" -#include "atom/browser/atom_browser_client.h" -#include "atom/browser/relauncher.h" -#include "atom/common/google_api_key.h" -#include "atom/renderer/atom_renderer_client.h" -#include "atom/utility/atom_content_utility_client.h" -#include "base/command_line.h" -#include "base/debug/stack_trace.h" -#include "base/environment.h" -#include "base/logging.h" -#include "chrome/common/chrome_paths.h" -#include "content/public/common/content_switches.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" - -namespace atom { - -namespace { - -const char* kRelauncherProcess = "relauncher"; - -bool IsBrowserProcess(base::CommandLine* cmd) { - std::string process_type = cmd->GetSwitchValueASCII(switches::kProcessType); - return process_type.empty(); -} - -#if defined(OS_WIN) -void InvalidParameterHandler(const wchar_t*, const wchar_t*, const wchar_t*, - unsigned int, uintptr_t) { - // noop. -} -#endif - -} // namespace - -AtomMainDelegate::AtomMainDelegate() { -} - -AtomMainDelegate::~AtomMainDelegate() { -} - -bool AtomMainDelegate::BasicStartupComplete(int* exit_code) { - auto command_line = base::CommandLine::ForCurrentProcess(); - - logging::LoggingSettings settings; -#if defined(OS_WIN) - // On Windows the terminal returns immediately, so we add a new line to - // prevent output in the same line as the prompt. - if (IsBrowserProcess(command_line)) - std::wcout << std::endl; -#if defined(DEBUG) - // Print logging to debug.log on Windows - settings.logging_dest = logging::LOG_TO_ALL; - settings.log_file = L"debug.log"; - settings.lock_log = logging::LOCK_LOG_FILE; - settings.delete_old = logging::DELETE_OLD_LOG_FILE; -#else - settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; -#endif // defined(DEBUG) -#else // defined(OS_WIN) - settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; -#endif // !defined(OS_WIN) - - // Only enable logging when --enable-logging is specified. - std::unique_ptr env(base::Environment::Create()); - if (!command_line->HasSwitch(switches::kEnableLogging) && - !env->HasVar("ELECTRON_ENABLE_LOGGING")) { - settings.logging_dest = logging::LOG_NONE; - logging::SetMinLogLevel(logging::LOG_NUM_SEVERITIES); - } - - logging::InitLogging(settings); - - // Logging with pid and timestamp. - logging::SetLogItems(true, false, true, false); - - // Enable convient stack printing. - bool enable_stack_dumping = env->HasVar("ELECTRON_ENABLE_STACK_DUMPING"); -#if defined(DEBUG) && defined(OS_LINUX) - enable_stack_dumping = true; -#endif - if (enable_stack_dumping) - base::debug::EnableInProcessStackDumping(); - - chrome::RegisterPathProvider(); - -#if defined(OS_MACOSX) - SetUpBundleOverrides(); -#endif - -#if defined(OS_WIN) - // Ignore invalid parameter errors. - _set_invalid_parameter_handler(InvalidParameterHandler); -#endif - - return brightray::MainDelegate::BasicStartupComplete(exit_code); -} - -void AtomMainDelegate::PreSandboxStartup() { - brightray::MainDelegate::PreSandboxStartup(); - - // Set google API key. - std::unique_ptr env(base::Environment::Create()); - if (!env->HasVar("GOOGLE_API_KEY")) - env->SetVar("GOOGLE_API_KEY", GOOGLEAPIS_API_KEY); - - auto command_line = base::CommandLine::ForCurrentProcess(); - std::string process_type = command_line->GetSwitchValueASCII( - switches::kProcessType); - - // Only append arguments for browser process. - if (!IsBrowserProcess(command_line)) - return; - - // Disable renderer sandbox for most of node's functions. - command_line->AppendSwitch(switches::kNoSandbox); - - // Allow file:// URIs to read other file:// URIs by default. - command_line->AppendSwitch(switches::kAllowFileAccessFromFiles); - -#if defined(OS_MACOSX) - // Enable AVFoundation. - command_line->AppendSwitch("enable-avfoundation"); -#endif -} - -content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() { - browser_client_.reset(new AtomBrowserClient); - return browser_client_.get(); -} - -content::ContentRendererClient* - AtomMainDelegate::CreateContentRendererClient() { - renderer_client_.reset(new AtomRendererClient); - return renderer_client_.get(); -} - -content::ContentUtilityClient* AtomMainDelegate::CreateContentUtilityClient() { - utility_client_.reset(new AtomContentUtilityClient); - return utility_client_.get(); -} - -int AtomMainDelegate::RunProcess( - const std::string& process_type, - const content::MainFunctionParams& main_function_params) { - if (process_type == kRelauncherProcess) - return relauncher::RelauncherMain(main_function_params); - else - return -1; -} - -#if defined(OS_MACOSX) -bool AtomMainDelegate::ShouldSendMachPort(const std::string& process_type) { - return process_type != kRelauncherProcess; -} - -bool AtomMainDelegate::DelaySandboxInitialization( - const std::string& process_type) { - return process_type == kRelauncherProcess; -} -#endif - -std::unique_ptr -AtomMainDelegate::CreateContentClient() { - return std::unique_ptr(new AtomContentClient); -} - -} // namespace atom +// Copyright (c) 2013 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/app/atom_main_delegate.h" + +#include +#include + +#include "atom/app/atom_content_client.h" +#include "atom/browser/atom_browser_client.h" +#include "atom/browser/relauncher.h" +#include "atom/common/google_api_key.h" +#include "atom/renderer/atom_renderer_client.h" +#include "atom/utility/atom_content_utility_client.h" +#include "base/command_line.h" +#include "base/debug/stack_trace.h" +#include "base/environment.h" +#include "base/logging.h" +#include "chrome/common/chrome_paths.h" +#include "content/public/common/content_switches.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" + +#include "base/memory/ptr_util.h" +#include "content/browser/renderer_host/render_view_host_impl.h" +#include "content/browser/renderer_host/render_widget_host_impl.h" +#include "atom/browser/osr_window.h" + +#include "content/browser/renderer_host/render_widget_host_view_aura.h" + +namespace atom { + +namespace { + +const char* kRelauncherProcess = "relauncher"; + +bool IsBrowserProcess(base::CommandLine* cmd) { + std::string process_type = cmd->GetSwitchValueASCII(switches::kProcessType); + return process_type.empty(); +} + +#if defined(OS_WIN) +void InvalidParameterHandler(const wchar_t*, const wchar_t*, const wchar_t*, + unsigned int, uintptr_t) { + // noop. +} +#endif + +} // namespace + +AtomMainDelegate::AtomMainDelegate() { +} + +AtomMainDelegate::~AtomMainDelegate() { +} + +bool AtomMainDelegate::BasicStartupComplete(int* exit_code) { + auto command_line = base::CommandLine::ForCurrentProcess(); + + logging::LoggingSettings settings; +#if defined(OS_WIN) + // On Windows the terminal returns immediately, so we add a new line to + // prevent output in the same line as the prompt. + if (IsBrowserProcess(command_line)) + std::wcout << std::endl; +#if defined(DEBUG) + // Print logging to debug.log on Windows + settings.logging_dest = logging::LOG_TO_ALL; + settings.log_file = L"debug.log"; + settings.lock_log = logging::LOCK_LOG_FILE; + settings.delete_old = logging::DELETE_OLD_LOG_FILE; +#else + settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; +#endif // defined(DEBUG) +#else // defined(OS_WIN) + settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; +#endif // !defined(OS_WIN) + + // Only enable logging when --enable-logging is specified. + std::unique_ptr env(base::Environment::Create()); + if (!command_line->HasSwitch(switches::kEnableLogging) && + !env->HasVar("ELECTRON_ENABLE_LOGGING")) { + settings.logging_dest = logging::LOG_NONE; + logging::SetMinLogLevel(logging::LOG_NUM_SEVERITIES); + } + + logging::InitLogging(settings); + + // Logging with pid and timestamp. + logging::SetLogItems(true, false, true, false); + + // Enable convient stack printing. + bool enable_stack_dumping = env->HasVar("ELECTRON_ENABLE_STACK_DUMPING"); +#if defined(DEBUG) && defined(OS_LINUX) + enable_stack_dumping = true; +#endif + if (enable_stack_dumping) + base::debug::EnableInProcessStackDumping(); + + chrome::RegisterPathProvider(); + +#if defined(OS_MACOSX) + SetUpBundleOverrides(); +#endif + +#if defined(OS_WIN) + // Ignore invalid parameter errors. + _set_invalid_parameter_handler(InvalidParameterHandler); +#endif + + render_view_host_factory_.reset(new AtomRenderViewHostFactory); + + return brightray::MainDelegate::BasicStartupComplete(exit_code); +} + +void AtomMainDelegate::PreSandboxStartup() { + brightray::MainDelegate::PreSandboxStartup(); + + // Set google API key. + std::unique_ptr env(base::Environment::Create()); + if (!env->HasVar("GOOGLE_API_KEY")) + env->SetVar("GOOGLE_API_KEY", GOOGLEAPIS_API_KEY); + + auto command_line = base::CommandLine::ForCurrentProcess(); + std::string process_type = command_line->GetSwitchValueASCII( + switches::kProcessType); + + // Only append arguments for browser process. + if (!IsBrowserProcess(command_line)) + return; + + // Disable renderer sandbox for most of node's functions. + command_line->AppendSwitch(switches::kNoSandbox); + + // Allow file:// URIs to read other file:// URIs by default. + command_line->AppendSwitch(switches::kAllowFileAccessFromFiles); + +#if defined(OS_MACOSX) + // Enable AVFoundation. + command_line->AppendSwitch("enable-avfoundation"); +#endif +} + +content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() { + browser_client_.reset(new AtomBrowserClient); + return browser_client_.get(); +} + +content::ContentRendererClient* + AtomMainDelegate::CreateContentRendererClient() { + renderer_client_.reset(new AtomRendererClient); + return renderer_client_.get(); +} + +content::ContentUtilityClient* AtomMainDelegate::CreateContentUtilityClient() { + utility_client_.reset(new AtomContentUtilityClient); + return utility_client_.get(); +} + +int AtomMainDelegate::RunProcess( + const std::string& process_type, + const content::MainFunctionParams& main_function_params) { + if (process_type == kRelauncherProcess) + return relauncher::RelauncherMain(main_function_params); + else + return -1; +} + +#if defined(OS_MACOSX) +bool AtomMainDelegate::ShouldSendMachPort(const std::string& process_type) { + return process_type != kRelauncherProcess; +} + +bool AtomMainDelegate::DelaySandboxInitialization( + const std::string& process_type) { + return process_type == kRelauncherProcess; +} +#endif + +std::unique_ptr +AtomMainDelegate::CreateContentClient() { + return std::unique_ptr(new AtomContentClient); +} + +AtomRenderViewHostFactory::AtomRenderViewHostFactory() { + //std::cout << "AtomRenderViewHostFactory" << std::endl; + content::RenderViewHostFactory::UnregisterFactory(); + content::RenderViewHostFactory::RegisterFactory( this ); +} + +AtomRenderViewHostFactory::~AtomRenderViewHostFactory() { + //std::cout << "~AtomRenderViewHostFactory" << std::endl; +} + +content::RenderViewHost* AtomRenderViewHostFactory::CreateRenderViewHost( + content::SiteInstance* instance, + content::RenderViewHostDelegate* delegate, + content::RenderWidgetHostDelegate* widget_delegate, + int32_t routing_id, + int32_t main_frame_routing_id, + bool swapped_out) { + + auto widget_host_impl = new content::RenderWidgetHostImpl( + widget_delegate, instance->GetProcess(), routing_id, false); + + auto view_host_impl = new content::RenderViewHostImpl(instance, + base::WrapUnique(widget_host_impl), delegate, main_frame_routing_id, + swapped_out, true); + + new OffScreenWindow(widget_host_impl); + + return view_host_impl; +} + +} // namespace atom diff --git a/atom/app/atom_main_delegate.h b/atom/app/atom_main_delegate.h index 58a380bd7d..f9c93076a1 100644 --- a/atom/app/atom_main_delegate.h +++ b/atom/app/atom_main_delegate.h @@ -1,57 +1,75 @@ -// Copyright (c) 2013 GitHub, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#ifndef ATOM_APP_ATOM_MAIN_DELEGATE_H_ -#define ATOM_APP_ATOM_MAIN_DELEGATE_H_ - -#include - -#include "brightray/common/main_delegate.h" -#include "brightray/common/content_client.h" - -namespace atom { - -class AtomMainDelegate : public brightray::MainDelegate { - public: - AtomMainDelegate(); - ~AtomMainDelegate(); - - protected: - // content::ContentMainDelegate: - bool BasicStartupComplete(int* exit_code) override; - void PreSandboxStartup() override; - content::ContentBrowserClient* CreateContentBrowserClient() override; - content::ContentRendererClient* CreateContentRendererClient() override; - content::ContentUtilityClient* CreateContentUtilityClient() override; - int RunProcess( - const std::string& process_type, - const content::MainFunctionParams& main_function_params) override; -#if defined(OS_MACOSX) - bool ShouldSendMachPort(const std::string& process_type) override; - bool DelaySandboxInitialization(const std::string& process_type) override; -#endif - - // brightray::MainDelegate: - std::unique_ptr CreateContentClient() override; -#if defined(OS_MACOSX) - void OverrideChildProcessPath() override; - void OverrideFrameworkBundlePath() override; -#endif - - private: -#if defined(OS_MACOSX) - void SetUpBundleOverrides(); -#endif - - brightray::ContentClient content_client_; - std::unique_ptr browser_client_; - std::unique_ptr renderer_client_; - std::unique_ptr utility_client_; - - DISALLOW_COPY_AND_ASSIGN(AtomMainDelegate); -}; - -} // namespace atom - -#endif // ATOM_APP_ATOM_MAIN_DELEGATE_H_ +// Copyright (c) 2013 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_APP_ATOM_MAIN_DELEGATE_H_ +#define ATOM_APP_ATOM_MAIN_DELEGATE_H_ + +#include + +#include "brightray/common/main_delegate.h" +#include "brightray/common/content_client.h" + +#include "content/browser/renderer_host/render_view_host_factory.h" + +namespace atom { + +class AtomRenderViewHostFactory : public content::RenderViewHostFactory { +public: + + AtomRenderViewHostFactory(); + ~AtomRenderViewHostFactory(); + + content::RenderViewHost* CreateRenderViewHost( + content::SiteInstance* instance, + content::RenderViewHostDelegate* delegate, + content::RenderWidgetHostDelegate* widget_delegate, + int32_t routing_id, + int32_t main_frame_routing_id, + bool swapped_out); +}; + +class AtomMainDelegate : public brightray::MainDelegate { + public: + AtomMainDelegate(); + ~AtomMainDelegate(); + + protected: + // content::ContentMainDelegate: + bool BasicStartupComplete(int* exit_code) override; + void PreSandboxStartup() override; + content::ContentBrowserClient* CreateContentBrowserClient() override; + content::ContentRendererClient* CreateContentRendererClient() override; + content::ContentUtilityClient* CreateContentUtilityClient() override; + int RunProcess( + const std::string& process_type, + const content::MainFunctionParams& main_function_params) override; +#if defined(OS_MACOSX) + bool ShouldSendMachPort(const std::string& process_type) override; + bool DelaySandboxInitialization(const std::string& process_type) override; +#endif + + // brightray::MainDelegate: + std::unique_ptr CreateContentClient() override; +#if defined(OS_MACOSX) + void OverrideChildProcessPath() override; + void OverrideFrameworkBundlePath() override; +#endif + + private: +#if defined(OS_MACOSX) + void SetUpBundleOverrides(); +#endif + + brightray::ContentClient content_client_; + std::unique_ptr browser_client_; + std::unique_ptr renderer_client_; + std::unique_ptr utility_client_; + std::unique_ptr render_view_host_factory_; + + DISALLOW_COPY_AND_ASSIGN(AtomMainDelegate); +}; + +} // namespace atom + +#endif // ATOM_APP_ATOM_MAIN_DELEGATE_H_ diff --git a/atom/browser/api/frame_subscriber.cc b/atom/browser/api/frame_subscriber.cc index 91b6765db1..7d87c6f0fc 100644 --- a/atom/browser/api/frame_subscriber.cc +++ b/atom/browser/api/frame_subscriber.cc @@ -9,10 +9,24 @@ #include "atom/common/native_mate_converters/gfx_converter.h" #include "content/public/browser/render_widget_host.h" +#include +#include "content/browser/compositor/image_transport_factory.h" +#include "cc/surfaces/surface_manager.h" +#include "cc/surfaces/surface.h" +#include "cc/output/copy_output_request.h" + namespace atom { namespace api { +FrameSubscriberRenderWidgetHostView::FrameSubscriberRenderWidgetHostView() { + std::cout << "FrameSubscriberRenderWidgetHostView" << std::endl; +} + +FrameSubscriberRenderWidgetHostView::~FrameSubscriberRenderWidgetHostView() { + std::cout << "~FrameSubscriberRenderWidgetHostView" << std::endl; +} + FrameSubscriber::FrameSubscriber(v8::Isolate* isolate, content::RenderWidgetHostView* view, const FrameCaptureCallback& callback, @@ -27,26 +41,51 @@ bool FrameSubscriber::ShouldCaptureFrame( scoped_refptr* storage, DeliverFrameCallback* callback) { const auto host = view_ ? view_->GetRenderWidgetHost() : nullptr; + if (!view_ || !host) return false; - if (dirty_rect.IsEmpty()) - return false; + /*if (dirty_rect.IsEmpty()) + return false;*/ gfx::Rect rect = gfx::Rect(view_->GetVisibleViewportSize()); if (only_dirty_) rect = dirty_rect; - host->CopyFromBackingStore( + /*host->CopyFromBackingStore( rect, rect.size(), base::Bind(&FrameSubscriber::OnFrameDelivered, weak_factory_.GetWeakPtr(), callback_, rect), - kBGRA_8888_SkColorType); + kBGRA_8888_SkColorType);*/ + const auto base = reinterpret_cast( + view_); + content::ImageTransportFactory* itf = + content::ImageTransportFactory::GetInstance(); + cc::SurfaceManager* sfm = itf->GetSurfaceManager(); + cc::Surface* surface = sfm->GetSurfaceForId(base->SurfaceIdForTesting()); + + std::unique_ptr request = + cc::CopyOutputRequest::CreateBitmapRequest( + base::Bind(&FrameSubscriber::ReadbackResultAsBitmap, + base::Unretained(this))); + + surface->RequestCopyOfOutput(std::move(request)); return false; } +void FrameSubscriber::ReadbackResultAsBitmap( + std::unique_ptr result) { + std::unique_ptr bitmap = result->TakeBitmap(); + + SkAutoPixmapUnlock res; + if (!bitmap->requestLock(&res)) + return; + + std::cout << res.pixmap().addr() << std::endl; +} + void FrameSubscriber::OnFrameDelivered(const FrameCaptureCallback& callback, const gfx::Rect& damage_rect, const SkBitmap& bitmap, content::ReadbackResponse response) { diff --git a/atom/browser/api/frame_subscriber.h b/atom/browser/api/frame_subscriber.h index b6cff3da81..6f2f7fc6f4 100644 --- a/atom/browser/api/frame_subscriber.h +++ b/atom/browser/api/frame_subscriber.h @@ -14,10 +14,24 @@ #include "ui/gfx/geometry/size.h" #include "v8/include/v8.h" +#include "content/browser/renderer_host/render_widget_host_view_base.h" +#include "cc/surfaces/surface_id.h" +#include "cc/output/copy_output_result.h" + namespace atom { namespace api { +class FrameSubscriberRenderWidgetHostView + : public content::RenderWidgetHostViewBase { + public: + + FrameSubscriberRenderWidgetHostView(); + ~FrameSubscriberRenderWidgetHostView(); + + cc::SurfaceId SurfaceId(); +}; + class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber { public: using FrameCaptureCallback = @@ -34,6 +48,9 @@ class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber { DeliverFrameCallback* callback) override; private: + void ReadbackResultAsBitmap( + std::unique_ptr result); + void OnFrameDelivered(const FrameCaptureCallback& callback, const gfx::Rect& damage_rect, const SkBitmap& bitmap, content::ReadbackResponse response); diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 1feb9618ac..568a21cb15 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -55,6 +55,15 @@ #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" #endif +#include +#include "atom/browser/osr_window.h" +#include "content/public/browser/render_widget_host.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/context_factory.h" +#include "base/single_thread_task_runner.h" +#include "base/threading/thread.h" +#include "ui/gfx/native_widget_types.h" + namespace atom { namespace { @@ -321,6 +330,21 @@ NativeWindowViews::~NativeWindowViews() { window_->RemoveObserver(this); } +void NativeWindowViews::RenderViewCreated( + content::RenderViewHost* render_view_host) { + std::cout << "NativeWindowViews::RenderViewCreated" << std::endl; + NativeWindow::RenderViewCreated(render_view_host); + + content::RenderWidgetHostImpl* impl = content::RenderWidgetHostImpl::FromID( + render_view_host->GetProcess()->GetID(), + render_view_host->GetRoutingID()); + if (impl) { + ui::Layer* layer = widget()->GetCompositor()->root_layer(); + ui::Compositor* compositor_ = widget()->GetCompositor(); + compositor_->RequestNewOutputSurface(); + } +} + void NativeWindowViews::Close() { if (!IsClosable()) { WindowList::WindowCloseCancelled(this); diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 69d3d27a35..921cb11824 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -49,6 +49,7 @@ class NativeWindowViews : public NativeWindow, ~NativeWindowViews() override; // NativeWindow: + void RenderViewCreated(content::RenderViewHost*) override; void Close() override; void CloseImmediately() override; void Focus(bool focus) override; diff --git a/atom/browser/osr_window.cc b/atom/browser/osr_window.cc new file mode 100644 index 0000000000..98e4b47cea --- /dev/null +++ b/atom/browser/osr_window.cc @@ -0,0 +1,623 @@ +// Copyright (c) 2013 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/osr_window.h" +#include "third_party/WebKit/public/platform/WebScreenInfo.h" +#include "content/browser/renderer_host/render_widget_host_impl.h" +#include "content/browser/renderer_host/render_widget_host_delegate.h" +#include "content/public/browser/render_widget_host_view_frame_subscriber.h" +#include "ui/events/latency_info.h" +#include "content/common/view_messages.h" +#include "ui/gfx/geometry/dip_util.h" +#include "base/memory/ptr_util.h" +#include "content/public/browser/context_factory.h" +#include "base/single_thread_task_runner.h" +#include "ui/compositor/layer.h" +#include "ui/compositor/layer_type.h" +#include "base/location.h" +#include "ui/gfx/native_widget_types.h" +#include +#include +#include + +#include "third_party/skia/include/core/SkSurface.h" +#include "third_party/skia/include/core/SkPixmap.h" +#include "cc/output/output_surface_client.h" + +#include "content/browser/compositor/software_browser_compositor_output_surface.h" + +namespace atom { + +OffScreenOutputSurface::OffScreenOutputSurface( + std::unique_ptr device) +: OutputSurface(nullptr, nullptr, std::move(device)) { + std::cout << "OffScreenOutputSurface" << std::endl; +} + +OffScreenOutputSurface::~OffScreenOutputSurface() { + std::cout << "~OffScreenOutputSurface" << std::endl; +} + +void OffScreenOutputSurface::SwapBuffers(cc::CompositorFrame* frame) { + std::cout << "SwapBuffers" << std::endl; + + base::TimeTicks swap_time = base::TimeTicks::Now(); + for (auto& latency : frame->metadata.latency_info) { + latency.AddLatencyNumberWithTimestamp( + ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0, swap_time, 1); + latency.AddLatencyNumberWithTimestamp( + ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0, + swap_time, 1); + } + + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(&content::RenderWidgetHostImpl::CompositorFrameDrawn, + frame->metadata.latency_info)); + + client_->DidSwapBuffers(); + PostSwapBuffersComplete(); +} + +bool OffScreenOutputSurface::BindToClient(cc::OutputSurfaceClient* client) { + client_ = client; + return true; +} + +OffScreenOutputDevice::OffScreenOutputDevice() { + std::cout << "OffScreenOutputDevice" << std::endl; +} + +OffScreenOutputDevice::~OffScreenOutputDevice() { + std::cout << "~OffScreenOutputDevice" << std::endl; +} + +// Discards any pre-existing backing buffers and allocates memory for a +// software device of |size|. This must be called before the +// |SoftwareOutputDevice| can be used in other ways. +void OffScreenOutputDevice::Resize( + const gfx::Size& pixel_size, float scale_factor) { + std::cout << "Resize" << std::endl; + + std::cout << pixel_size.width() << "x" << pixel_size.height() << std::endl; + + scale_factor_ = scale_factor; + if (viewport_pixel_size_ == pixel_size) + return; + viewport_pixel_size_ = pixel_size; + + surface_ = SkSurface::MakeRasterN32Premul( + viewport_pixel_size_.width(), viewport_pixel_size_.height()); +} + +// Called on BeginDrawingFrame. The compositor will draw into the returned +// SkCanvas. The |SoftwareOutputDevice| implementation needs to provide a +// valid SkCanvas of at least size |damage_rect|. This class retains ownership +// of the SkCanvas. +SkCanvas* OffScreenOutputDevice::BeginPaint(const gfx::Rect& damage_rect) { + std::cout << "BeginPaint" << std::endl; + damage_rect_ = damage_rect; + if (surface_.get()) + return surface_->getCanvas(); + + return nullptr; +} + +// Called on FinishDrawingFrame. The compositor will no longer mutate the the +// SkCanvas instance returned by |BeginPaint| and should discard any reference +// that it holds to it. +void OffScreenOutputDevice::EndPaint() { + std::cout << "EndPaint" << std::endl; + SkPixmap pixmap; + if (surface_->peekPixels(&pixmap)) { + std::cout << "OK" << std::endl; + for(int i = 0; i < 10; i++) { + const uint8_t* addr = reinterpret_cast(pixmap.addr(50,i)); + for(int j = 0; j < 4; j++) + std::cout << std::hex << static_cast(*(addr + j)) << std::dec << " "; + std::cout << std::endl; + } + } +} + +// Discard the backing buffer in the surface provided by this instance. +void OffScreenOutputDevice::DiscardBackbuffer() { + std::cout << "DiscardBackbuffer" << std::endl; +} + +// Ensures that there is a backing buffer available on this instance. +void OffScreenOutputDevice::EnsureBackbuffer() { + std::cout << "EnsureBackbuffer" << std::endl; +} + +// VSyncProvider used to update the timer used to schedule draws with the +// hardware vsync. Return NULL if a provider doesn't exist. +gfx::VSyncProvider* OffScreenOutputDevice::GetVSyncProvider() { + std::cout << "GetVSyncProvider" << std::endl; + return nullptr; +} + +OffScreenWindow::OffScreenWindow( + content::RenderWidgetHost* host) + : host_(content::RenderWidgetHostImpl::From(host)), + delegated_frame_host_(new content::DelegatedFrameHost(this)), + focus_(false), + size_(gfx::Size(0,0)), + scale_(0.0) { + std::cout << "OffScreenWindow" << std::endl; + //std::this_thread::sleep_for(std::chrono::milliseconds(5000)); + host_->SetView(this); + + SetLayer(new ui::Layer(ui::LayerType::LAYER_SOLID_COLOR)); + layer()->SetVisible(true); + layer()->set_delegate(this); + layer()->set_name("OffScreenWindowLayer"); + layer()->SetFillsBoundsOpaquely(false); + + ui::ContextFactory* factory = content::GetContextFactory(); + thread_ = new base::Thread("Compositor"); + thread_->Start(); + + //compositor_ = new ui::Compositor(factory, thread_->task_runner()); + compositor_ = new ui::Compositor( + factory, base::ThreadTaskRunnerHandle::Get()); + delegated_frame_host_->ResetCompositor(); + delegated_frame_host_->SetCompositor(compositor_); + compositor_->SetRootLayer(layer()); + + set_layer_owner_delegate(delegated_frame_host_); + + std::unique_ptr device(new OffScreenOutputDevice()); + std::unique_ptr output_surface( + new OffScreenOutputSurface( + std::move(device))); + + std::unique_ptr window_(new AtomCompositorHostWin()); + + compositor_->SetOutputSurface(std::move(output_surface)); + compositor_->SetAcceleratedWidget(window_->hwnd()); + std::cout << compositor_ << std::endl; +} + +OffScreenWindow::~OffScreenWindow() { + std::cout << "~OffScreenWindow" << std::endl; +} + +bool OffScreenWindow::OnMessageReceived(const IPC::Message& message) { + std::cout << "OnMessageReceived" << std::endl; + std::cout << message.type() << std::endl; + + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(OffScreenWindow, message) + IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrames, + OnSetNeedsBeginFrames) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +void OffScreenWindow::InitAsChild(gfx::NativeView) { + std::cout << "InitAsChild" << std::endl; +} + +content::RenderWidgetHost* OffScreenWindow::GetRenderWidgetHost() const { + std::cout << "GetRenderWidgetHost" << std::endl; + return host_; +} + +void OffScreenWindow::SetSize(const gfx::Size& new_size) { + std::cout << "SetSize" << std::endl; + std::cout << new_size.width() << "x" << new_size.height() << std::endl; + size_ = new_size; + compositor_->SetScaleAndSize(scale_, size_); +} + +void OffScreenWindow::SetBounds(const gfx::Rect& new_bounds) { + std::cout << "SetBounds" << std::endl; + std::cout << new_bounds.width() << "x" << new_bounds.height() << std::endl; +} + +gfx::Vector2dF OffScreenWindow::GetLastScrollOffset() const { + std::cout << "GetLastScrollOffset" << std::endl; + return last_scroll_offset_; +} + +gfx::NativeView OffScreenWindow::GetNativeView() const { + std::cout << "GetNativeView" << std::endl; + return static_cast(NULL); +} + +gfx::NativeViewId OffScreenWindow::GetNativeViewId() const { + std::cout << "GetNativeViewId" << std::endl; + return static_cast(NULL); +} + +gfx::NativeViewAccessible OffScreenWindow::GetNativeViewAccessible() { + std::cout << "GetNativeViewAccessible" << std::endl; + return static_cast(NULL); +} + +ui::TextInputClient* OffScreenWindow::GetTextInputClient() { + std::cout << "GetTextInputClient" << std::endl; + return nullptr; +} + +void OffScreenWindow::Focus() { + std::cout << "Focus" << std::endl; + focus_ = true; +} + +bool OffScreenWindow::HasFocus() const { + std::cout << "HasFocus" << std::endl; + return focus_; +} + +bool OffScreenWindow::IsSurfaceAvailableForCopy() const { + std::cout << "IsSurfaceAvailableForCopy" << std::endl; + return delegated_frame_host_->CanCopyToBitmap(); +} + +void OffScreenWindow::Show() { + std::cout << "Show" << std::endl; + ui::LatencyInfo latency_info; + + if (delegated_frame_host_->HasSavedFrame()) + latency_info.AddLatencyNumber( + ui::TAB_SHOW_COMPONENT, host_->GetLatencyComponentId(), 0); + + delegated_frame_host_->WasShown(latency_info); +} + +void OffScreenWindow::Hide() { + std::cout << "Hide" << std::endl; + if (host_ && !host_->is_hidden()) + delegated_frame_host_->WasHidden(); +} + +bool OffScreenWindow::IsShowing() { + std::cout << "IsShowing" << std::endl; + return true; +} + +gfx::Rect OffScreenWindow::GetViewBounds() const { + std::cout << "GetViewBounds" << std::endl; + return gfx::Rect(size_); +} + +gfx::Size OffScreenWindow::GetVisibleViewportSize() const { + std::cout << "GetVisibleViewportSize" << std::endl; + return size_; +} + +void OffScreenWindow::SetInsets(const gfx::Insets& insets) { + std::cout << "SetInsets" << std::endl; + host_->WasResized(); +} + +bool OffScreenWindow::LockMouse() { + std::cout << "LockMouse" << std::endl; + return false; +} + +void OffScreenWindow::UnlockMouse() { + std::cout << "UnlockMouse" << std::endl; +} + +bool OffScreenWindow::GetScreenColorProfile(std::vector*) { + std::cout << "GetScreenColorProfile" << std::endl; + return false; +} + +void OffScreenWindow::ClearCompositorFrame() { + std::cout << "ClearCompositorFrame" << std::endl; + delegated_frame_host_->ClearDelegatedFrame(); +} + +void OffScreenWindow::InitAsPopup(content::RenderWidgetHostView *, const gfx::Rect &) { + std::cout << "InitAsPopup" << std::endl; +} + +void OffScreenWindow::InitAsFullscreen(content::RenderWidgetHostView *) { + std::cout << "InitAsFullscreen" << std::endl; +} + +void OffScreenWindow::UpdateCursor(const content::WebCursor &) { + std::cout << "UpdateCursor" << std::endl; +} + +void OffScreenWindow::SetIsLoading(bool loading) { + std::cout << "SetIsLoading" << std::endl; + if (!loading) { + std::cout << "IsDrawn" << std::endl; + std::cout << layer()->IsDrawn() << std::endl; + layer()->SchedulePaint(gfx::Rect(size_)); + } +} + +void OffScreenWindow::TextInputStateChanged(const ViewHostMsg_TextInputState_Params &) { + std::cout << "TextInputStateChanged" << std::endl; +} + +void OffScreenWindow::ImeCancelComposition() { + std::cout << "ImeCancelComposition" << std::endl; +} + +void OffScreenWindow::RenderProcessGone(base::TerminationStatus,int) { + std::cout << "RenderProcessGone" << std::endl; + Destroy(); +} + +void OffScreenWindow::Destroy() { + std::cout << "Destroy" << std::endl; + thread_->Stop(); +} + +void OffScreenWindow::SetTooltipText(const base::string16 &) { + std::cout << "SetTooltipText" << std::endl; +} + +void OffScreenWindow::SelectionBoundsChanged(const ViewHostMsg_SelectionBounds_Params &) { + std::cout << "SelectionBoundsChanged" << std::endl; +} + +void OffScreenWindow::CopyFromCompositingSurface(const gfx::Rect& src_subrect, + const gfx::Size& dst_size, + const content::ReadbackRequestCallback& callback, + const SkColorType preferred_color_type) { + delegated_frame_host_->CopyFromCompositingSurface( + src_subrect, dst_size, callback, preferred_color_type); + std::cout << "CopyFromCompositingSurface" << std::endl; + delegated_frame_host_->CopyFromCompositingSurface( + src_subrect, dst_size, callback, preferred_color_type); +} + +void OffScreenWindow::CopyFromCompositingSurfaceToVideoFrame( + const gfx::Rect& src_subrect, + const scoped_refptr& target, + const base::Callback& callback) { + delegated_frame_host_->CopyFromCompositingSurfaceToVideoFrame( + src_subrect, target, callback); + std::cout << "CopyFromCompositingSurfaceToVideoFrame" << std::endl; + delegated_frame_host_->CopyFromCompositingSurfaceToVideoFrame( + src_subrect, target, callback); +} + +bool OffScreenWindow::CanCopyToVideoFrame() const { + std::cout << "CanCopyToVideoFrame" << std::endl; + return delegated_frame_host_->CanCopyToVideoFrame(); +} + +void OffScreenWindow::BeginFrameSubscription( + std::unique_ptr subscriber) { + std::cout << "BeginFrameSubscription" << std::endl; + delegated_frame_host_->BeginFrameSubscription(std::move(subscriber)); +} + +void OffScreenWindow::EndFrameSubscription() { + std::cout << "EndFrameSubscription" << std::endl; + delegated_frame_host_->EndFrameSubscription(); +} + +bool OffScreenWindow::HasAcceleratedSurface(const gfx::Size &) { + std::cout << "HasAcceleratedSurface" << std::endl; + return false; +} + +void OffScreenWindow::GetScreenInfo(blink::WebScreenInfo* results) { + std::cout << "GetScreenInfo" << std::endl; + + results->rect = gfx::Rect(size_); + results->availableRect = gfx::Rect(size_); + results->depth = 24; + results->depthPerComponent = 8; + results->deviceScaleFactor = scale_; + results->orientationAngle = 0; + results->orientationType = blink::WebScreenOrientationLandscapePrimary; +} + +bool OffScreenWindow::GetScreenColorProfile(blink::WebVector*) { + std::cout << "GetScreenColorProfile" << std::endl; + return false; +} + +gfx::Rect OffScreenWindow::GetBoundsInRootWindow() { + std::cout << "GetBoundsInRootWindow" << std::endl; + return gfx::Rect(size_); +} + +void OffScreenWindow::LockCompositingSurface() { + std::cout << "LockCompositingSurface" << std::endl; +} + +void OffScreenWindow::UnlockCompositingSurface() { + std::cout << "UnlockCompositingSurface" << std::endl; +} + +void OffScreenWindow::ImeCompositionRangeChanged( + const gfx::Range &, const std::vector&) { + std::cout << "ImeCompositionRangeChanged" << std::endl; +} + +int OffScreenWindow::DelegatedFrameHostGetGpuMemoryBufferClientId() const { + std::cout << "DelegatedFrameHostGetGpuMemoryBufferClientId" << std::endl; + return host_->GetProcess()->GetID(); +} + +ui::Layer* OffScreenWindow::DelegatedFrameHostGetLayer() const { + std::cout << "DelegatedFrameHostGetLayer" << std::endl; + return const_cast(layer()); +} + +bool OffScreenWindow::DelegatedFrameHostIsVisible() const { + std::cout << "DelegatedFrameHostIsVisible" << std::endl; + std::cout << !host_->is_hidden() << std::endl; + return !host_->is_hidden(); +} + +SkColor OffScreenWindow::DelegatedFrameHostGetGutterColor(SkColor color) const { + std::cout << "DelegatedFrameHostGetGutterColor" << std::endl; + return color; +} + +gfx::Size OffScreenWindow::DelegatedFrameHostDesiredSizeInDIP() const { + std::cout << "DelegatedFrameHostDesiredSizeInDIP" << std::endl; + return size_; +} + +bool OffScreenWindow::DelegatedFrameCanCreateResizeLock() const { + std::cout << "DelegatedFrameCanCreateResizeLock" << std::endl; + return false; +} + +std::unique_ptr + OffScreenWindow::DelegatedFrameHostCreateResizeLock(bool) { + std::cout << "DelegatedFrameHostCreateResizeLock" << std::endl; + return nullptr; +} + +void OffScreenWindow::DelegatedFrameHostResizeLockWasReleased() { + std::cout << "DelegatedFrameHostResizeLockWasReleased" << std::endl; + host_->WasResized(); +} + +void OffScreenWindow::DelegatedFrameHostSendCompositorSwapAck( + int output_surface_id, const cc::CompositorFrameAck& ack) { + std::cout << "DelegatedFrameHostSendCompositorSwapAck" << std::endl; + host_->Send(new ViewMsg_SwapCompositorFrameAck(host_->GetRoutingID(), + output_surface_id, ack)); +} + +void OffScreenWindow::DelegatedFrameHostSendReclaimCompositorResources( + int output_surface_id, const cc::CompositorFrameAck& ack) { + std::cout << "DelegatedFrameHostSendReclaimCompositorResources" << std::endl; + host_->Send(new ViewMsg_ReclaimCompositorResources(host_->GetRoutingID(), + output_surface_id, ack)); +} + +void OffScreenWindow::DelegatedFrameHostOnLostCompositorResources() { + std::cout << "DelegatedFrameHostOnLostCompositorResources" << std::endl; + host_->ScheduleComposite(); +} + +void OffScreenWindow::DelegatedFrameHostUpdateVSyncParameters( + const base::TimeTicks& timebase, const base::TimeDelta& interval) { + std::cout << "DelegatedFrameHostUpdateVSyncParameters" << std::endl; + host_->UpdateVSyncParameters(timebase, interval); +} + + + +void OffScreenWindow::OnBeginFrame(const cc::BeginFrameArgs& args) { + std::cout << "OnBeginFrame" << std::endl; + + delegated_frame_host_->SetVSyncParameters(args.frame_time, args.interval); + host_->Send(new ViewMsg_BeginFrame(host_->GetRoutingID(), args)); + last_begin_frame_args_ = args; +} + +const cc::BeginFrameArgs& OffScreenWindow::LastUsedBeginFrameArgs() const { + std::cout << "LastUsedBeginFrameArgs" << std::endl; + return last_begin_frame_args_; +} + +void OffScreenWindow::OnBeginFrameSourcePausedChanged(bool) { + std::cout << "OnBeginFrameSourcePausedChanged" << std::endl; +} + +void OffScreenWindow::AsValueInto(base::trace_event::TracedValue *) const { + std::cout << "AsValueInto" << std::endl; +} + +gfx::Size OffScreenWindow::GetPhysicalBackingSize() const { + std::cout << "GetPhysicalBackingSize" << std::endl; + return size_; +} + +void OffScreenWindow::UpdateScreenInfo(gfx::NativeView view) { + std::cout << "UpdateScreenInfo" << std::endl; + content::RenderWidgetHostImpl* impl = NULL; + if (GetRenderWidgetHost()) + impl = content::RenderWidgetHostImpl::From(GetRenderWidgetHost()); + + if (impl && impl->delegate()) + impl->delegate()->SendScreenRects(); + + if (HasDisplayPropertyChanged(view) && impl) + impl->NotifyScreenInfoChanged(); +} + +gfx::Size OffScreenWindow::GetRequestedRendererSize() const { + std::cout << "GetRequestedRendererSize" << std::endl; + gfx::Size size = delegated_frame_host_->GetRequestedRendererSize(); + + std::cout << size.width() << "x" << size.height() << std::endl; + + return size; +} + +void OffScreenWindow::OnSwapCompositorFrame(uint32_t output_surface_id, + cc::CompositorFrame frame) { + std::cout << "OnSwapCompositorFrame" << std::endl; + + last_scroll_offset_ = frame.metadata.root_scroll_offset; + if (!frame.delegated_frame_data) return; + + delegated_frame_host_->SwapDelegatedFrame( + output_surface_id, base::WrapUnique(&frame)); +} + +uint32_t OffScreenWindow::SurfaceIdNamespaceAtPoint( + cc::SurfaceHittestDelegate* delegate, + const gfx::Point& point, + gfx::Point* transformed_point) { + std::cout << "SurfaceIdNamespaceAtPoint" << std::endl; + + gfx::Point point_in_pixels = gfx::ConvertPointToPixel(scale_, point); + cc::SurfaceId id = delegated_frame_host_->SurfaceIdAtPoint( + delegate, point_in_pixels, transformed_point); + *transformed_point = gfx::ConvertPointToDIP(scale_, *transformed_point); + + if (id.is_null()) + return GetSurfaceIdNamespace(); + return id.id_namespace(); +} + +uint32_t OffScreenWindow::GetSurfaceIdNamespace() { + std::cout << "GetSurfaceIdNamespace" << std::endl; + return delegated_frame_host_->GetSurfaceIdNamespace(); +} + +void OffScreenWindow::OnPaintLayer(const ui::PaintContext &) { + std::cout << "OnPaintLayer" << std::endl; +} + +void OffScreenWindow::OnDelegatedFrameDamage(const gfx::Rect &) { + std::cout << "OnDelegatedFrameDamage" << std::endl; +} + +void OffScreenWindow::OnDeviceScaleFactorChanged(float scale) { + std::cout << "OnDeviceScaleFactorChanged" << std::endl; + scale_ = scale; +} + +base::Closure OffScreenWindow::PrepareForLayerBoundsChange() { + std::cout << "PrepareForLayerBoundsChange" << std::endl; + return base::Bind(&OffScreenWindow::OnBoundsChanged, base::Unretained(this)); +} + +void OffScreenWindow::OnBoundsChanged() { + std::cout << "OnBoundsChanged" << std::endl; +} + +void OffScreenWindow::OnSetNeedsBeginFrames(bool needs_begin_frames) { + std::cout << "OnSetNeedsBeginFrames" << std::endl; +} + +void OffScreenWindow::SendSwapCompositorFrame(cc::CompositorFrame* frame) { + std::cout << "SendSwapCompositorFrame" << std::endl; + std::vector messages_to_deliver_with_frame; + /*host_->Send(new ViewHostMsg_SwapCompositorFrame(host_->GetRoutingID(), + 10, *frame, messages_to_deliver_with_frame));*/ +} + +} // namespace atom diff --git a/atom/browser/osr_window.h b/atom/browser/osr_window.h new file mode 100644 index 0000000000..ac5545f9a2 --- /dev/null +++ b/atom/browser/osr_window.h @@ -0,0 +1,206 @@ +// Copyright (c) 2013 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_OSR_WINDOW_H_ +#define ATOM_BROWSER_OSR_WINDOW_H_ + +#include "content/browser/renderer_host/render_widget_host_view_base.h" +#include "content/browser/renderer_host/delegated_frame_host.h" +#include "content/browser/renderer_host/resize_lock.h" +#include "third_party/WebKit/public/platform/WebVector.h" +#include "cc/scheduler/begin_frame_source.h" +#include "content/browser/renderer_host/render_widget_host_impl.h" +#include "cc/output/compositor_frame.h" +#include "ui/gfx/geometry/point.h" +#include "base/threading/thread.h" +#include "ui/compositor/compositor.h" +#include "ui/compositor/layer_delegate.h" +#include "ui/compositor/layer_owner.h" +#include "ui/base/ime/text_input_client.h" +#include "base/process/kill.h" + +#include "cc/output/software_output_device.h" +#include "cc/output/output_surface.h" +#include "cc/output/output_surface_client.h" +#include "cc/scheduler/begin_frame_source.h" + +#include +#include "ui/gfx/win/window_impl.h" + +namespace atom { + +class AtomCompositorHostWin : public gfx::WindowImpl { + public: + AtomCompositorHostWin() { + // Create a hidden 1x1 borderless window. + set_window_style(WS_POPUP | WS_SYSMENU); + Init(NULL, gfx::Rect(0, 0, 1, 1)); + } + + ~AtomCompositorHostWin() override { + DestroyWindow(hwnd()); + } + + private: + CR_BEGIN_MSG_MAP_EX(CompositorHostWin) + CR_MSG_WM_PAINT(OnPaint) + CR_END_MSG_MAP() + + void OnPaint(HDC dc) { + ValidateRect(hwnd(), NULL); + } +}; + +class OffScreenWindow + : public content::RenderWidgetHostViewBase, + public content::DelegatedFrameHostClient, + public cc::BeginFrameObserver, + public ui::LayerDelegate, + public ui::LayerOwner { +public: + OffScreenWindow(content::RenderWidgetHost*); + ~OffScreenWindow(); + +//content::RenderWidgetHostView + bool OnMessageReceived(const IPC::Message&) override; + void InitAsChild(gfx::NativeView); + content::RenderWidgetHost* GetRenderWidgetHost(void) const; + void SetSize(const gfx::Size &); + void SetBounds(const gfx::Rect &); + gfx::Vector2dF GetLastScrollOffset(void) const; + gfx::NativeView GetNativeView(void) const; + gfx::NativeViewId GetNativeViewId(void) const; + gfx::NativeViewAccessible GetNativeViewAccessible(void); + ui::TextInputClient* GetTextInputClient() override; + void Focus(void); + bool HasFocus(void) const; + bool IsSurfaceAvailableForCopy(void) const; + void Show(void); + void Hide(void); + bool IsShowing(void); + gfx::Rect GetViewBounds(void) const; + gfx::Size GetVisibleViewportSize() const override; + void SetInsets(const gfx::Insets&) override; + bool LockMouse(void); + void UnlockMouse(void); + bool GetScreenColorProfile(std::vector*); + +//content::RenderWidgetHostViewBase + void ClearCompositorFrame(void); + void InitAsPopup(content::RenderWidgetHostView *, const gfx::Rect &); + void InitAsFullscreen(content::RenderWidgetHostView *); + void UpdateCursor(const content::WebCursor &); + void SetIsLoading(bool); + void TextInputStateChanged(const ViewHostMsg_TextInputState_Params &); + void ImeCancelComposition(void); + void RenderProcessGone(base::TerminationStatus,int); + void Destroy(void); + void SetTooltipText(const base::string16 &); + void SelectionBoundsChanged(const ViewHostMsg_SelectionBounds_Params &); + void CopyFromCompositingSurface(const gfx::Rect &, + const gfx::Size &, + const content::ReadbackRequestCallback &, + const SkColorType); + void CopyFromCompositingSurfaceToVideoFrame( + const gfx::Rect &, + const scoped_refptr &, + const base::Callback &); + bool CanCopyToVideoFrame(void) const; + void BeginFrameSubscription( + std::unique_ptr); + void EndFrameSubscription(); + bool HasAcceleratedSurface(const gfx::Size &); + void GetScreenInfo(blink::WebScreenInfo *); + bool GetScreenColorProfile(blink::WebVector*); + gfx::Rect GetBoundsInRootWindow(void); + void LockCompositingSurface(void); + void UnlockCompositingSurface(void); + void ImeCompositionRangeChanged( + const gfx::Range &, const std::vector&); + +//content::DelegatedFrameHostClient + int DelegatedFrameHostGetGpuMemoryBufferClientId(void) const; + ui::Layer *DelegatedFrameHostGetLayer(void) const; + bool DelegatedFrameHostIsVisible(void) const; + SkColor DelegatedFrameHostGetGutterColor(SkColor) const; + gfx::Size DelegatedFrameHostDesiredSizeInDIP(void) const; + bool DelegatedFrameCanCreateResizeLock(void) const; + std::unique_ptr DelegatedFrameHostCreateResizeLock(bool); + void DelegatedFrameHostResizeLockWasReleased(void); + void DelegatedFrameHostSendCompositorSwapAck( + int, const cc::CompositorFrameAck &); + void DelegatedFrameHostSendReclaimCompositorResources( + int, const cc::CompositorFrameAck &); + void DelegatedFrameHostOnLostCompositorResources(void); + void DelegatedFrameHostUpdateVSyncParameters( + const base::TimeTicks &, const base::TimeDelta &); + +//cc::BeginFrameObserver + void OnBeginFrame(const cc::BeginFrameArgs &); + const cc::BeginFrameArgs & LastUsedBeginFrameArgs(void) const; + void OnBeginFrameSourcePausedChanged(bool); + void AsValueInto(base::trace_event::TracedValue *) const; + + gfx::Size GetPhysicalBackingSize() const; + void UpdateScreenInfo(gfx::NativeView view); + gfx::Size GetRequestedRendererSize() const; + void OnSwapCompositorFrame(uint32_t, cc::CompositorFrame); + uint32_t SurfaceIdNamespaceAtPoint( + cc::SurfaceHittestDelegate* delegate, + const gfx::Point& point, + gfx::Point* transformed_point); + uint32_t GetSurfaceIdNamespace(); + + void OnPaintLayer(const ui::PaintContext &); + void OnDelegatedFrameDamage(const gfx::Rect &); + void OnDeviceScaleFactorChanged(float); + base::Closure PrepareForLayerBoundsChange(); + void OnBoundsChanged(); + + void OnSetNeedsBeginFrames(bool); + void SendSwapCompositorFrame(cc::CompositorFrame *); +private: + content::RenderWidgetHostImpl* host_; + content::DelegatedFrameHost* delegated_frame_host_; + gfx::Vector2dF last_scroll_offset_; + bool focus_; + gfx::Size size_; + float scale_; + + cc::BeginFrameSource* begin_frame_source_; + cc::BeginFrameArgs last_begin_frame_args_; + bool needs_begin_frames_; + + base::Thread* thread_; + ui::Compositor* compositor_; +}; + +class OffScreenOutputSurface : public cc::OutputSurface { +public: + OffScreenOutputSurface( + std::unique_ptr); + ~OffScreenOutputSurface(); + + void SwapBuffers(cc::CompositorFrame *); + bool BindToClient(cc::OutputSurfaceClient *); +}; + +class OffScreenOutputDevice : public cc::SoftwareOutputDevice { +public: + OffScreenOutputDevice(); + ~OffScreenOutputDevice(); + + void Resize(const gfx::Size& pixel_size, float scale_factor); + SkCanvas* BeginPaint(const gfx::Rect& damage_rect); + void EndPaint(); + void DiscardBackbuffer(); + void EnsureBackbuffer(); + gfx::VSyncProvider* GetVSyncProvider(); +}; + + +} // namespace atom + +#endif // ATOM_BROWSER_OSR_WINDOW_H_ diff --git a/default_app/default_app.js b/default_app/default_app.js index a72675ea6f..9f28872735 100644 --- a/default_app/default_app.js +++ b/default_app/default_app.js @@ -18,5 +18,10 @@ exports.load = (appUrl) => { }) mainWindow.loadURL(appUrl) mainWindow.focus() + mainWindow.webContents.on('dom-ready', () => { + mainWindow.webContents.beginFrameSubscription(() => { + console.log("asd") + }) + }) }) } diff --git a/filenames.gypi b/filenames.gypi index af7080821b..7c655b86ce 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -203,6 +203,8 @@ 'atom/browser/native_window_mac.h', 'atom/browser/native_window_mac.mm', 'atom/browser/native_window_observer.h', + 'atom/browser/osr_window.cc', + 'atom/browser/osr_window.h', 'atom/browser/net/asar/asar_protocol_handler.cc', 'atom/browser/net/asar/asar_protocol_handler.h', 'atom/browser/net/asar/url_request_asar_job.cc', From 6e25aea49f09c3fd51c5822d6ddc47908057724e Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Wed, 13 Jul 2016 17:43:00 +0200 Subject: [PATCH 2/8] speed(up) bump --- atom/app/atom_main_delegate.cc | 7 +- atom/browser/common_web_contents_delegate.cc | 18 +- atom/browser/native_window_views.cc | 9 +- atom/browser/osr_window.cc | 643 +++++++++++-------- atom/browser/osr_window.h | 159 ++--- atom/browser/osr_window_win.cc | 41 ++ filenames.gypi | 1 + 7 files changed, 530 insertions(+), 348 deletions(-) create mode 100644 atom/browser/osr_window_win.cc diff --git a/atom/app/atom_main_delegate.cc b/atom/app/atom_main_delegate.cc index 891cdd3056..89851e0780 100644 --- a/atom/app/atom_main_delegate.cc +++ b/atom/app/atom_main_delegate.cc @@ -27,7 +27,7 @@ #include "content/browser/renderer_host/render_widget_host_impl.h" #include "atom/browser/osr_window.h" -#include "content/browser/renderer_host/render_widget_host_view_aura.h" +#include "content/public/browser/web_contents.h" namespace atom { @@ -201,6 +201,9 @@ content::RenderViewHost* AtomRenderViewHostFactory::CreateRenderViewHost( int32_t main_frame_routing_id, bool swapped_out) { + std::cout << delegate << std::endl; + std::cout << widget_delegate << std::endl; + auto widget_host_impl = new content::RenderWidgetHostImpl( widget_delegate, instance->GetProcess(), routing_id, false); @@ -208,7 +211,7 @@ content::RenderViewHost* AtomRenderViewHostFactory::CreateRenderViewHost( base::WrapUnique(widget_host_impl), delegate, main_frame_routing_id, swapped_out, true); - new OffScreenWindow(widget_host_impl); + //new OffScreenWindow(widget_host_impl); return view_host_impl; } diff --git a/atom/browser/common_web_contents_delegate.cc b/atom/browser/common_web_contents_delegate.cc index c275d4aee7..80a9bc211b 100644 --- a/atom/browser/common_web_contents_delegate.cc +++ b/atom/browser/common_web_contents_delegate.cc @@ -8,6 +8,8 @@ #include #include +#include + #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_javascript_dialog_manager.h" #include "atom/browser/atom_security_state_model_client.h" @@ -31,6 +33,10 @@ #include "content/public/browser/security_style_explanations.h" #include "storage/browser/fileapi/isolated_context.h" +#include "content/browser/web_contents/web_contents_impl.h" +#include "atom/browser/osr_window.h" +#include "atom/browser/native_window_views.h" + using content::BrowserThread; using security_state::SecurityStateModel; @@ -182,18 +188,26 @@ void CommonWebContentsDelegate::InitWithWebContents( printing::PrintViewManagerBasic::CreateForWebContents(web_contents); printing::PrintPreviewMessageHandler::CreateForWebContents(web_contents); + content::WebContentsImpl* impl = + reinterpret_cast(web_contents); + + impl->SetView(new OffScreenWebContentsView); + std::cout << "end" << std::endl; // Create InspectableWebContents. - web_contents_.reset(brightray::InspectableWebContents::Create(web_contents)); - web_contents_->SetDelegate(this); + /*web_contents_.reset(brightray::InspectableWebContents::Create(web_contents)); + web_contents_->SetDelegate(this);*/ + std::cout << "end" << std::endl; } void CommonWebContentsDelegate::SetOwnerWindow(NativeWindow* owner_window) { + std::cout << "SetOwnerWindow" << std::endl; SetOwnerWindow(GetWebContents(), owner_window); } void CommonWebContentsDelegate::SetOwnerWindow( content::WebContents* web_contents, NativeWindow* owner_window) { owner_window_ = owner_window->GetWeakPtr(); + NativeWindowRelay* relay = new NativeWindowRelay(owner_window_); web_contents->SetUserData(relay->key, relay); } diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 2edee730d6..930500142a 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -339,9 +339,12 @@ void NativeWindowViews::RenderViewCreated( render_view_host->GetProcess()->GetID(), render_view_host->GetRoutingID()); if (impl) { - ui::Layer* layer = widget()->GetCompositor()->root_layer(); - ui::Compositor* compositor_ = widget()->GetCompositor(); - compositor_->RequestNewOutputSurface(); + //auto win = new OffScreenWindow(impl); + + /*auto view = widget()->GetContentsView(); + view->AcquireLayer(); + view->SetLayer(win->DelegatedFrameHostGetLayer()); + win->DelegatedFrameHostGetLayer()->set_delegate(view);*/ } } diff --git a/atom/browser/osr_window.cc b/atom/browser/osr_window.cc index 98e4b47cea..ed4eeb691e 100644 --- a/atom/browser/osr_window.cc +++ b/atom/browser/osr_window.cc @@ -25,45 +25,152 @@ #include "third_party/skia/include/core/SkPixmap.h" #include "cc/output/output_surface_client.h" -#include "content/browser/compositor/software_browser_compositor_output_surface.h" - namespace atom { -OffScreenOutputSurface::OffScreenOutputSurface( - std::unique_ptr device) -: OutputSurface(nullptr, nullptr, std::move(device)) { - std::cout << "OffScreenOutputSurface" << std::endl; +OffScreenWebContentsView::OffScreenWebContentsView() { + std::cout << "OffScreenWebContentsView" << std::endl; + //std::this_thread::sleep_for(std::chrono::milliseconds(10000)); +} +OffScreenWebContentsView::~OffScreenWebContentsView() { + std::cout << "~OffScreenWebContentsView" << std::endl; } -OffScreenOutputSurface::~OffScreenOutputSurface() { - std::cout << "~OffScreenOutputSurface" << std::endl; +// Returns the native widget that contains the contents of the tab. +gfx::NativeView OffScreenWebContentsView::GetNativeView() const{ + std::cout << "GetNativeView" << std::endl; + return gfx::NativeView(); } -void OffScreenOutputSurface::SwapBuffers(cc::CompositorFrame* frame) { - std::cout << "SwapBuffers" << std::endl; - - base::TimeTicks swap_time = base::TimeTicks::Now(); - for (auto& latency : frame->metadata.latency_info) { - latency.AddLatencyNumberWithTimestamp( - ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0, swap_time, 1); - latency.AddLatencyNumberWithTimestamp( - ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0, - swap_time, 1); - } - - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&content::RenderWidgetHostImpl::CompositorFrameDrawn, - frame->metadata.latency_info)); - - client_->DidSwapBuffers(); - PostSwapBuffersComplete(); +// Returns the native widget with the main content of the tab (i.e. the main +// render view host, though there may be many popups in the tab as children of +// the container). +gfx::NativeView OffScreenWebContentsView::GetContentNativeView() const{ + std::cout << "GetContentNativeView" << std::endl; + return gfx::NativeView(); } -bool OffScreenOutputSurface::BindToClient(cc::OutputSurfaceClient* client) { - client_ = client; - return true; +// Returns the outermost native view. This will be used as the parent for +// dialog boxes. +gfx::NativeWindow OffScreenWebContentsView::GetTopLevelNativeWindow() const{ + std::cout << "GetTopLevelNativeWindow" << std::endl; + return gfx::NativeWindow(); } +// Computes the rectangle for the native widget that contains the contents of +// the tab in the screen coordinate system. +void OffScreenWebContentsView::GetContainerBounds(gfx::Rect* out) const{ + std::cout << "GetContainerBounds" << std::endl; + *out = GetViewBounds(); +} + +// TODO(brettw) this is a hack. It's used in two places at the time of this +// writing: (1) when render view hosts switch, we need to size the replaced +// one to be correct, since it wouldn't have known about sizes that happened +// while it was hidden; (2) in constrained windows. +// +// (1) will be fixed once interstitials are cleaned up. (2) seems like it +// should be cleaned up or done some other way, since this works for normal +// WebContents without the special code. +void OffScreenWebContentsView::SizeContents(const gfx::Size& size){ + std::cout << "SizeContents" << std::endl; +} + +// Sets focus to the native widget for this tab. +void OffScreenWebContentsView::Focus(){ + std::cout << "OffScreenWebContentsView::Focus" << std::endl; +} + +// Sets focus to the appropriate element when the WebContents is shown the +// first time. +void OffScreenWebContentsView::SetInitialFocus(){ + std::cout << "SetInitialFocus" << std::endl; +} + +// Stores the currently focused view. +void OffScreenWebContentsView::StoreFocus(){ + std::cout << "StoreFocus" << std::endl; +} + +// Restores focus to the last focus view. If StoreFocus has not yet been +// invoked, SetInitialFocus is invoked. +void OffScreenWebContentsView::RestoreFocus(){ + std::cout << "RestoreFocus" << std::endl; +} + +// Returns the current drop data, if any. +content::DropData* OffScreenWebContentsView::GetDropData() const{ + std::cout << "GetDropData" << std::endl; + return nullptr; +} + +// Get the bounds of the View, relative to the parent. +gfx::Rect OffScreenWebContentsView::GetViewBounds() const{ + std::cout << "OffScreenWebContentsView::GetViewBounds" << std::endl; + return view_ ? view_->GetViewBounds() : gfx::Rect(); +} + +void OffScreenWebContentsView::CreateView( + const gfx::Size& initial_size, gfx::NativeView context){ + std::cout << "CreateView" << std::endl; + std::cout << initial_size.width() << "x" << initial_size.height() << std::endl; +} + +// Sets up the View that holds the rendered web page, receives messages for +// it and contains page plugins. The host view should be sized to the current +// size of the WebContents. +// +// |is_guest_view_hack| is temporary hack and will be removed once +// RenderWidgetHostViewGuest is not dependent on platform view. +// TODO(lazyboy): Remove |is_guest_view_hack| once http://crbug.com/330264 is +// fixed. +content::RenderWidgetHostViewBase* + OffScreenWebContentsView::CreateViewForWidget( + content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack){ + std::cout << "CreateViewForWidget" << std::endl; + view_ = new OffScreenWindow(render_widget_host); + return view_; +} + +// Creates a new View that holds a popup and receives messages for it. +content::RenderWidgetHostViewBase* + OffScreenWebContentsView::CreateViewForPopupWidget( + content::RenderWidgetHost* render_widget_host){ + std::cout << "CreateViewForPopupWidget" << std::endl; + view_ = new OffScreenWindow(render_widget_host); + return view_; +} + +// Sets the page title for the native widgets corresponding to the view. This +// is not strictly necessary and isn't expected to be displayed anywhere, but +// can aid certain debugging tools such as Spy++ on Windows where you are +// trying to find a specific window. +void OffScreenWebContentsView::SetPageTitle(const base::string16& title){ + std::cout << "SetPageTitle" << std::endl; + std::cout << title << std::endl; +} + +// Invoked when the WebContents is notified that the RenderView has been +// fully created. +void OffScreenWebContentsView::RenderViewCreated(content::RenderViewHost* host){ + std::cout << "RenderViewCreated" << std::endl; +} + +// Invoked when the WebContents is notified that the RenderView has been +// swapped in. +void OffScreenWebContentsView::RenderViewSwappedIn(content::RenderViewHost* host){ + std::cout << "RenderViewSwappedIn" << std::endl; +} + +// Invoked to enable/disable overscroll gesture navigation. +void OffScreenWebContentsView::SetOverscrollControllerEnabled(bool enabled){ + std::cout << "SetOverscrollControllerEnabled" << std::endl; +} + + + + + + OffScreenOutputDevice::OffScreenOutputDevice() { std::cout << "OffScreenOutputDevice" << std::endl; } @@ -72,120 +179,190 @@ OffScreenOutputDevice::~OffScreenOutputDevice() { std::cout << "~OffScreenOutputDevice" << std::endl; } -// Discards any pre-existing backing buffers and allocates memory for a -// software device of |size|. This must be called before the -// |SoftwareOutputDevice| can be used in other ways. void OffScreenOutputDevice::Resize( const gfx::Size& pixel_size, float scale_factor) { std::cout << "Resize" << std::endl; - std::cout << pixel_size.width() << "x" << pixel_size.height() << std::endl; scale_factor_ = scale_factor; - if (viewport_pixel_size_ == pixel_size) - return; + + if (viewport_pixel_size_ == pixel_size) return; viewport_pixel_size_ = pixel_size; - surface_ = SkSurface::MakeRasterN32Premul( - viewport_pixel_size_.width(), viewport_pixel_size_.height()); + canvas_.reset(NULL); + bitmap_.reset(new SkBitmap); + bitmap_->allocN32Pixels(viewport_pixel_size_.width(), + viewport_pixel_size_.height(), + false); + if (bitmap_->drawsNothing()) { + std::cout << "drawsNothing" << std::endl; + NOTREACHED(); + bitmap_.reset(NULL); + return; + } + bitmap_->eraseARGB(0, 0, 0, 0); + + canvas_.reset(new SkCanvas(*bitmap_.get())); } -// Called on BeginDrawingFrame. The compositor will draw into the returned -// SkCanvas. The |SoftwareOutputDevice| implementation needs to provide a -// valid SkCanvas of at least size |damage_rect|. This class retains ownership -// of the SkCanvas. SkCanvas* OffScreenOutputDevice::BeginPaint(const gfx::Rect& damage_rect) { std::cout << "BeginPaint" << std::endl; - damage_rect_ = damage_rect; - if (surface_.get()) - return surface_->getCanvas(); + DCHECK(canvas_.get()); + DCHECK(bitmap_.get()); - return nullptr; + damage_rect_ = damage_rect; + + return canvas_.get(); +} + +void OffScreenOutputDevice::saveSkBitmapToBMPFile(const SkBitmap& skBitmap, const char* path){ + typedef unsigned char UINT8; + typedef signed char SINT8; + typedef unsigned short UINT16; + typedef signed short SINT16; + typedef unsigned int UINT32; + typedef signed int SINT32; + + struct BMP_FILEHDR // BMP file header + { + UINT32 bfSize; // size of file + UINT16 bfReserved1; + UINT16 bfReserved2; + UINT32 bfOffBits; // pointer to the pixmap bits + }; + + struct BMP_INFOHDR // BMP information header + { + UINT32 biSize; // size of this struct + UINT32 biWidth; // pixmap width + UINT32 biHeight; // pixmap height + UINT16 biPlanes; // should be 1 + UINT16 biBitCount; // number of bits per pixel + UINT32 biCompression; // compression method + UINT32 biSizeImage; // size of image + UINT32 biXPelsPerMeter; // horizontal resolution + UINT32 biYPelsPerMeter; // vertical resolution + UINT32 biClrUsed; // number of colors used + UINT32 biClrImportant; // number of important colors + }; + #define BitmapColorGetA(color) (((color) >> 24) & 0xFF) + #define BitmapColorGetR(color) (((color) >> 16) & 0xFF) + #define BitmapColorGetG(color) (((color) >> 8) & 0xFF) + #define BitmapColorGetB(color) (((color) >> 0) & 0xFF) + + int bmpWidth = skBitmap.width(); + int bmpHeight = skBitmap.height(); + int stride = skBitmap.rowBytes(); + char* m_pmap = (char*)skBitmap.getPixels(); + //virtual PixelFormat& GetPixelFormat() =0; //assume pf is ARGB; + FILE* fp = fopen(path, "wb"); + if(!fp){ + printf("saveSkBitmapToBMPFile: fopen %s Error!\n", path); + } + SINT32 bpl=bmpWidth*4; + // BMP file header. + BMP_FILEHDR fhdr; + fputc('B', fp); + fputc('M', fp); + fhdr.bfReserved1=fhdr.bfReserved2=0; + fhdr.bfOffBits=14+40; // File header size + header size. + fhdr.bfSize=fhdr.bfOffBits+bpl*bmpHeight; + fwrite(&fhdr, 1, 12, fp); + + // BMP header. + BMP_INFOHDR bhdr; + bhdr.biSize=40; + bhdr.biBitCount=32; + bhdr.biCompression=0; // RGB Format. + bhdr.biPlanes=1; + bhdr.biWidth=bmpWidth; + bhdr.biHeight=bmpHeight; + bhdr.biClrImportant=0; + bhdr.biClrUsed=0; + bhdr.biXPelsPerMeter=2384; + bhdr.biYPelsPerMeter=2384; + bhdr.biSizeImage=bpl*bmpHeight; + fwrite(&bhdr, 1, 40, fp); + + // BMP data. + //for(UINT32 y=0; y=0; y--) + { + SINT32 base=y*stride; + for(SINT32 x=0; x<(SINT32)bmpWidth; x++) + { + UINT32 i=base+x*4; + UINT32 pixelData = *(UINT32*)(m_pmap+i); + UINT8 b1=BitmapColorGetB(pixelData); + UINT8 g1=BitmapColorGetG(pixelData); + UINT8 r1=BitmapColorGetR(pixelData); + UINT8 a1=BitmapColorGetA(pixelData); + r1=r1*a1/255; + g1=g1*a1/255; + b1=b1*a1/255; + UINT32 temp=(a1<<24)|(r1<<16)|(g1<<8)|b1;//a bmp pixel in little endian is B、G、R、A + fwrite(&temp, 4, 1, fp); + } + } + fflush(fp); + fclose(fp); } -// Called on FinishDrawingFrame. The compositor will no longer mutate the the -// SkCanvas instance returned by |BeginPaint| and should discard any reference -// that it holds to it. void OffScreenOutputDevice::EndPaint() { std::cout << "EndPaint" << std::endl; - SkPixmap pixmap; - if (surface_->peekPixels(&pixmap)) { - std::cout << "OK" << std::endl; - for(int i = 0; i < 10; i++) { - const uint8_t* addr = reinterpret_cast(pixmap.addr(50,i)); - for(int j = 0; j < 4; j++) - std::cout << std::hex << static_cast(*(addr + j)) << std::dec << " "; - std::cout << std::endl; - } + + DCHECK(canvas_.get()); + DCHECK(bitmap_.get()); + + if (!bitmap_.get()) return; + + cc::SoftwareOutputDevice::EndPaint(); + + SkAutoLockPixels bitmap_pixels_lock(*bitmap_.get()); + //saveSkBitmapToBMPFile(*(bitmap_.get()), "test.bmp"); + + uint8_t* pixels = reinterpret_cast(bitmap_->getPixels()); + for (int i = 0; i<4; i++) { + int x = static_cast(pixels[i]); + std::cout << std::hex << x << std::dec << std::endl; } } -// Discard the backing buffer in the surface provided by this instance. -void OffScreenOutputDevice::DiscardBackbuffer() { - std::cout << "DiscardBackbuffer" << std::endl; -} - -// Ensures that there is a backing buffer available on this instance. -void OffScreenOutputDevice::EnsureBackbuffer() { - std::cout << "EnsureBackbuffer" << std::endl; -} - -// VSyncProvider used to update the timer used to schedule draws with the -// hardware vsync. Return NULL if a provider doesn't exist. -gfx::VSyncProvider* OffScreenOutputDevice::GetVSyncProvider() { - std::cout << "GetVSyncProvider" << std::endl; - return nullptr; -} - -OffScreenWindow::OffScreenWindow( - content::RenderWidgetHost* host) - : host_(content::RenderWidgetHostImpl::From(host)), +OffScreenWindow::OffScreenWindow(content::RenderWidgetHost* host) + : render_widget_host_(content::RenderWidgetHostImpl::From(host)), delegated_frame_host_(new content::DelegatedFrameHost(this)), - focus_(false), - size_(gfx::Size(0,0)), - scale_(0.0) { + compositor_widget_(gfx::kNullAcceleratedWidget), + scale_factor_(1.0f), + is_showing_(!render_widget_host_->is_hidden()), + size_(gfx::Size(800, 600)), + weak_ptr_factory_(this) { + DCHECK(render_widget_host_); std::cout << "OffScreenWindow" << std::endl; - //std::this_thread::sleep_for(std::chrono::milliseconds(5000)); - host_->SetView(this); + render_widget_host_->SetView(this); - SetLayer(new ui::Layer(ui::LayerType::LAYER_SOLID_COLOR)); - layer()->SetVisible(true); - layer()->set_delegate(this); - layer()->set_name("OffScreenWindowLayer"); - layer()->SetFillsBoundsOpaquely(false); + root_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR)); - ui::ContextFactory* factory = content::GetContextFactory(); - thread_ = new base::Thread("Compositor"); - thread_->Start(); + CreatePlatformWidget(); - //compositor_ = new ui::Compositor(factory, thread_->task_runner()); - compositor_ = new ui::Compositor( - factory, base::ThreadTaskRunnerHandle::Get()); - delegated_frame_host_->ResetCompositor(); - delegated_frame_host_->SetCompositor(compositor_); - compositor_->SetRootLayer(layer()); - - set_layer_owner_delegate(delegated_frame_host_); - - std::unique_ptr device(new OffScreenOutputDevice()); - std::unique_ptr output_surface( - new OffScreenOutputSurface( - std::move(device))); - - std::unique_ptr window_(new AtomCompositorHostWin()); - - compositor_->SetOutputSurface(std::move(output_surface)); - compositor_->SetAcceleratedWidget(window_->hwnd()); - std::cout << compositor_ << std::endl; + compositor_.reset(new ui::Compositor(content::GetContextFactory(), + base::ThreadTaskRunnerHandle::Get())); + compositor_->SetAcceleratedWidget(compositor_widget_); + compositor_->SetDelegate(this); + compositor_->SetRootLayer(root_layer_.get()); } OffScreenWindow::~OffScreenWindow() { std::cout << "~OffScreenWindow" << std::endl; + if (is_showing_) delegated_frame_host_->WasHidden(); + delegated_frame_host_->ResetCompositor(); + + delegated_frame_host_.reset(NULL); + compositor_.reset(NULL); + root_layer_.reset(NULL); } bool OffScreenWindow::OnMessageReceived(const IPC::Message& message) { std::cout << "OnMessageReceived" << std::endl; - std::cout << message.type() << std::endl; bool handled = true; IPC_BEGIN_MESSAGE_MAP(OffScreenWindow, message) @@ -193,6 +370,9 @@ bool OffScreenWindow::OnMessageReceived(const IPC::Message& message) { OnSetNeedsBeginFrames) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() + + if (!handled) + return content::RenderWidgetHostViewBase::OnMessageReceived(message); return handled; } @@ -202,19 +382,24 @@ void OffScreenWindow::InitAsChild(gfx::NativeView) { content::RenderWidgetHost* OffScreenWindow::GetRenderWidgetHost() const { std::cout << "GetRenderWidgetHost" << std::endl; - return host_; + return render_widget_host_; } -void OffScreenWindow::SetSize(const gfx::Size& new_size) { +void OffScreenWindow::SetSize(const gfx::Size& size) { std::cout << "SetSize" << std::endl; - std::cout << new_size.width() << "x" << new_size.height() << std::endl; - size_ = new_size; - compositor_->SetScaleAndSize(scale_, size_); + size_ = size; + + std::cout << size.width() << "x" << size.height() << std::endl; + + const gfx::Size& size_in_pixels = + gfx::ConvertSizeToPixel(scale_factor_, size); + + root_layer_->SetBounds(gfx::Rect(size)); + compositor_->SetScaleAndSize(scale_factor_, size_in_pixels); } void OffScreenWindow::SetBounds(const gfx::Rect& new_bounds) { std::cout << "SetBounds" << std::endl; - std::cout << new_bounds.width() << "x" << new_bounds.height() << std::endl; } gfx::Vector2dF OffScreenWindow::GetLastScrollOffset() const { @@ -224,17 +409,17 @@ gfx::Vector2dF OffScreenWindow::GetLastScrollOffset() const { gfx::NativeView OffScreenWindow::GetNativeView() const { std::cout << "GetNativeView" << std::endl; - return static_cast(NULL); + return gfx::NativeView(); } gfx::NativeViewId OffScreenWindow::GetNativeViewId() const { std::cout << "GetNativeViewId" << std::endl; - return static_cast(NULL); + return gfx::NativeViewId(); } gfx::NativeViewAccessible OffScreenWindow::GetNativeViewAccessible() { std::cout << "GetNativeViewAccessible" << std::endl; - return static_cast(NULL); + return gfx::NativeViewAccessible(); } ui::TextInputClient* OffScreenWindow::GetTextInputClient() { @@ -244,12 +429,11 @@ ui::TextInputClient* OffScreenWindow::GetTextInputClient() { void OffScreenWindow::Focus() { std::cout << "Focus" << std::endl; - focus_ = true; } bool OffScreenWindow::HasFocus() const { std::cout << "HasFocus" << std::endl; - return focus_; + return false; } bool OffScreenWindow::IsSurfaceAvailableForCopy() const { @@ -259,39 +443,45 @@ bool OffScreenWindow::IsSurfaceAvailableForCopy() const { void OffScreenWindow::Show() { std::cout << "Show" << std::endl; - ui::LatencyInfo latency_info; + if (is_showing_) + return; - if (delegated_frame_host_->HasSavedFrame()) - latency_info.AddLatencyNumber( - ui::TAB_SHOW_COMPONENT, host_->GetLatencyComponentId(), 0); - - delegated_frame_host_->WasShown(latency_info); + is_showing_ = true; + if (render_widget_host_) render_widget_host_->WasShown(ui::LatencyInfo()); + delegated_frame_host_->SetCompositor(compositor_.get()); + delegated_frame_host_->WasShown(ui::LatencyInfo()); } void OffScreenWindow::Hide() { std::cout << "Hide" << std::endl; - if (host_ && !host_->is_hidden()) - delegated_frame_host_->WasHidden(); + if (!is_showing_) + return; + + if (render_widget_host_) render_widget_host_->WasHidden(); + delegated_frame_host_->WasHidden(); + delegated_frame_host_->ResetCompositor(); + is_showing_ = false; } bool OffScreenWindow::IsShowing() { std::cout << "IsShowing" << std::endl; - return true; + return is_showing_; } gfx::Rect OffScreenWindow::GetViewBounds() const { std::cout << "GetViewBounds" << std::endl; + std::cout << size_.width() << "x" << size_.height() << std::endl; return gfx::Rect(size_); } gfx::Size OffScreenWindow::GetVisibleViewportSize() const { std::cout << "GetVisibleViewportSize" << std::endl; + std::cout << size_.width() << "x" << size_.height() << std::endl; return size_; } void OffScreenWindow::SetInsets(const gfx::Insets& insets) { std::cout << "SetInsets" << std::endl; - host_->WasResized(); } bool OffScreenWindow::LockMouse() { @@ -308,12 +498,32 @@ bool OffScreenWindow::GetScreenColorProfile(std::vector*) { return false; } +void OffScreenWindow::OnSwapCompositorFrame( + uint32_t output_surface_id, + std::unique_ptr frame) { + std::cout << "OnSwapCompositorFrame" << std::endl; + + std::cout << output_surface_id << std::endl; + + if (frame->delegated_frame_data) + std::cout << "delegated_frame_data" << std::endl; + + if (frame->metadata.root_scroll_offset != last_scroll_offset_) { + last_scroll_offset_ = frame->metadata.root_scroll_offset; + } + + if (frame->delegated_frame_data) + delegated_frame_host_->SwapDelegatedFrame( + output_surface_id, std::move(frame)); +} + void OffScreenWindow::ClearCompositorFrame() { std::cout << "ClearCompositorFrame" << std::endl; delegated_frame_host_->ClearDelegatedFrame(); } -void OffScreenWindow::InitAsPopup(content::RenderWidgetHostView *, const gfx::Rect &) { +void OffScreenWindow::InitAsPopup( + content::RenderWidgetHostView *, const gfx::Rect &) { std::cout << "InitAsPopup" << std::endl; } @@ -327,14 +537,10 @@ void OffScreenWindow::UpdateCursor(const content::WebCursor &) { void OffScreenWindow::SetIsLoading(bool loading) { std::cout << "SetIsLoading" << std::endl; - if (!loading) { - std::cout << "IsDrawn" << std::endl; - std::cout << layer()->IsDrawn() << std::endl; - layer()->SchedulePaint(gfx::Rect(size_)); - } } -void OffScreenWindow::TextInputStateChanged(const ViewHostMsg_TextInputState_Params &) { +void OffScreenWindow::TextInputStateChanged( + const ViewHostMsg_TextInputState_Params &) { std::cout << "TextInputStateChanged" << std::endl; } @@ -349,14 +555,14 @@ void OffScreenWindow::RenderProcessGone(base::TerminationStatus,int) { void OffScreenWindow::Destroy() { std::cout << "Destroy" << std::endl; - thread_->Stop(); } void OffScreenWindow::SetTooltipText(const base::string16 &) { std::cout << "SetTooltipText" << std::endl; } -void OffScreenWindow::SelectionBoundsChanged(const ViewHostMsg_SelectionBounds_Params &) { +void OffScreenWindow::SelectionBoundsChanged( + const ViewHostMsg_SelectionBounds_Params &) { std::cout << "SelectionBoundsChanged" << std::endl; } @@ -364,8 +570,6 @@ void OffScreenWindow::CopyFromCompositingSurface(const gfx::Rect& src_subrect, const gfx::Size& dst_size, const content::ReadbackRequestCallback& callback, const SkColorType preferred_color_type) { - delegated_frame_host_->CopyFromCompositingSurface( - src_subrect, dst_size, callback, preferred_color_type); std::cout << "CopyFromCompositingSurface" << std::endl; delegated_frame_host_->CopyFromCompositingSurface( src_subrect, dst_size, callback, preferred_color_type); @@ -375,8 +579,6 @@ void OffScreenWindow::CopyFromCompositingSurfaceToVideoFrame( const gfx::Rect& src_subrect, const scoped_refptr& target, const base::Callback& callback) { - delegated_frame_host_->CopyFromCompositingSurfaceToVideoFrame( - src_subrect, target, callback); std::cout << "CopyFromCompositingSurfaceToVideoFrame" << std::endl; delegated_frame_host_->CopyFromCompositingSurfaceToVideoFrame( src_subrect, target, callback); @@ -405,12 +607,12 @@ bool OffScreenWindow::HasAcceleratedSurface(const gfx::Size &) { void OffScreenWindow::GetScreenInfo(blink::WebScreenInfo* results) { std::cout << "GetScreenInfo" << std::endl; - + std::cout << size_.width() << "x" << size_.height() << std::endl; results->rect = gfx::Rect(size_); results->availableRect = gfx::Rect(size_); results->depth = 24; results->depthPerComponent = 8; - results->deviceScaleFactor = scale_; + results->deviceScaleFactor = scale_factor_; results->orientationAngle = 0; results->orientationType = blink::WebScreenOrientationLandscapePrimary; } @@ -422,6 +624,7 @@ bool OffScreenWindow::GetScreenColorProfile(blink::WebVector*) { gfx::Rect OffScreenWindow::GetBoundsInRootWindow() { std::cout << "GetBoundsInRootWindow" << std::endl; + std::cout << size_.width() << "x" << size_.height() << std::endl; return gfx::Rect(size_); } @@ -438,20 +641,30 @@ void OffScreenWindow::ImeCompositionRangeChanged( std::cout << "ImeCompositionRangeChanged" << std::endl; } +gfx::Size OffScreenWindow::GetPhysicalBackingSize() const { + std::cout << "GetPhysicalBackingSize" << std::endl; + return size_; +} + +gfx::Size OffScreenWindow::GetRequestedRendererSize() const { + std::cout << "GetRequestedRendererSize" << std::endl; + return size_; +} + int OffScreenWindow::DelegatedFrameHostGetGpuMemoryBufferClientId() const { std::cout << "DelegatedFrameHostGetGpuMemoryBufferClientId" << std::endl; - return host_->GetProcess()->GetID(); + return render_widget_host_->GetProcess()->GetID(); } ui::Layer* OffScreenWindow::DelegatedFrameHostGetLayer() const { std::cout << "DelegatedFrameHostGetLayer" << std::endl; - return const_cast(layer()); + return const_cast(root_layer_.get()); } bool OffScreenWindow::DelegatedFrameHostIsVisible() const { std::cout << "DelegatedFrameHostIsVisible" << std::endl; - std::cout << !host_->is_hidden() << std::endl; - return !host_->is_hidden(); + std::cout << !render_widget_host_->is_hidden() << std::endl; + return !render_widget_host_->is_hidden(); } SkColor OffScreenWindow::DelegatedFrameHostGetGutterColor(SkColor color) const { @@ -461,6 +674,7 @@ SkColor OffScreenWindow::DelegatedFrameHostGetGutterColor(SkColor color) const { gfx::Size OffScreenWindow::DelegatedFrameHostDesiredSizeInDIP() const { std::cout << "DelegatedFrameHostDesiredSizeInDIP" << std::endl; + std::cout << size_.width() << "x" << size_.height() << std::endl; return size_; } @@ -477,147 +691,46 @@ std::unique_ptr void OffScreenWindow::DelegatedFrameHostResizeLockWasReleased() { std::cout << "DelegatedFrameHostResizeLockWasReleased" << std::endl; - host_->WasResized(); + return render_widget_host_->WasResized(); } void OffScreenWindow::DelegatedFrameHostSendCompositorSwapAck( int output_surface_id, const cc::CompositorFrameAck& ack) { std::cout << "DelegatedFrameHostSendCompositorSwapAck" << std::endl; - host_->Send(new ViewMsg_SwapCompositorFrameAck(host_->GetRoutingID(), + std::cout << output_surface_id << std::endl; + render_widget_host_->Send(new ViewMsg_SwapCompositorFrameAck( + render_widget_host_->GetRoutingID(), output_surface_id, ack)); } void OffScreenWindow::DelegatedFrameHostSendReclaimCompositorResources( int output_surface_id, const cc::CompositorFrameAck& ack) { std::cout << "DelegatedFrameHostSendReclaimCompositorResources" << std::endl; - host_->Send(new ViewMsg_ReclaimCompositorResources(host_->GetRoutingID(), + std::cout << output_surface_id << std::endl; + render_widget_host_->Send(new ViewMsg_ReclaimCompositorResources( + render_widget_host_->GetRoutingID(), output_surface_id, ack)); } void OffScreenWindow::DelegatedFrameHostOnLostCompositorResources() { std::cout << "DelegatedFrameHostOnLostCompositorResources" << std::endl; - host_->ScheduleComposite(); + render_widget_host_->ScheduleComposite(); } void OffScreenWindow::DelegatedFrameHostUpdateVSyncParameters( const base::TimeTicks& timebase, const base::TimeDelta& interval) { std::cout << "DelegatedFrameHostUpdateVSyncParameters" << std::endl; - host_->UpdateVSyncParameters(timebase, interval); + render_widget_host_->UpdateVSyncParameters(timebase, interval); } - - -void OffScreenWindow::OnBeginFrame(const cc::BeginFrameArgs& args) { - std::cout << "OnBeginFrame" << std::endl; - - delegated_frame_host_->SetVSyncParameters(args.frame_time, args.interval); - host_->Send(new ViewMsg_BeginFrame(host_->GetRoutingID(), args)); - last_begin_frame_args_ = args; +std::unique_ptr + OffScreenWindow::CreateSoftwareOutputDevice(ui::Compositor* compositor) { + std::cout << "CreateSoftwareOutputDevice" << std::endl; + return std::unique_ptr(new OffScreenOutputDevice); } -const cc::BeginFrameArgs& OffScreenWindow::LastUsedBeginFrameArgs() const { - std::cout << "LastUsedBeginFrameArgs" << std::endl; - return last_begin_frame_args_; -} - -void OffScreenWindow::OnBeginFrameSourcePausedChanged(bool) { - std::cout << "OnBeginFrameSourcePausedChanged" << std::endl; -} - -void OffScreenWindow::AsValueInto(base::trace_event::TracedValue *) const { - std::cout << "AsValueInto" << std::endl; -} - -gfx::Size OffScreenWindow::GetPhysicalBackingSize() const { - std::cout << "GetPhysicalBackingSize" << std::endl; - return size_; -} - -void OffScreenWindow::UpdateScreenInfo(gfx::NativeView view) { - std::cout << "UpdateScreenInfo" << std::endl; - content::RenderWidgetHostImpl* impl = NULL; - if (GetRenderWidgetHost()) - impl = content::RenderWidgetHostImpl::From(GetRenderWidgetHost()); - - if (impl && impl->delegate()) - impl->delegate()->SendScreenRects(); - - if (HasDisplayPropertyChanged(view) && impl) - impl->NotifyScreenInfoChanged(); -} - -gfx::Size OffScreenWindow::GetRequestedRendererSize() const { - std::cout << "GetRequestedRendererSize" << std::endl; - gfx::Size size = delegated_frame_host_->GetRequestedRendererSize(); - - std::cout << size.width() << "x" << size.height() << std::endl; - - return size; -} - -void OffScreenWindow::OnSwapCompositorFrame(uint32_t output_surface_id, - cc::CompositorFrame frame) { - std::cout << "OnSwapCompositorFrame" << std::endl; - - last_scroll_offset_ = frame.metadata.root_scroll_offset; - if (!frame.delegated_frame_data) return; - - delegated_frame_host_->SwapDelegatedFrame( - output_surface_id, base::WrapUnique(&frame)); -} - -uint32_t OffScreenWindow::SurfaceIdNamespaceAtPoint( - cc::SurfaceHittestDelegate* delegate, - const gfx::Point& point, - gfx::Point* transformed_point) { - std::cout << "SurfaceIdNamespaceAtPoint" << std::endl; - - gfx::Point point_in_pixels = gfx::ConvertPointToPixel(scale_, point); - cc::SurfaceId id = delegated_frame_host_->SurfaceIdAtPoint( - delegate, point_in_pixels, transformed_point); - *transformed_point = gfx::ConvertPointToDIP(scale_, *transformed_point); - - if (id.is_null()) - return GetSurfaceIdNamespace(); - return id.id_namespace(); -} - -uint32_t OffScreenWindow::GetSurfaceIdNamespace() { - std::cout << "GetSurfaceIdNamespace" << std::endl; - return delegated_frame_host_->GetSurfaceIdNamespace(); -} - -void OffScreenWindow::OnPaintLayer(const ui::PaintContext &) { - std::cout << "OnPaintLayer" << std::endl; -} - -void OffScreenWindow::OnDelegatedFrameDamage(const gfx::Rect &) { - std::cout << "OnDelegatedFrameDamage" << std::endl; -} - -void OffScreenWindow::OnDeviceScaleFactorChanged(float scale) { - std::cout << "OnDeviceScaleFactorChanged" << std::endl; - scale_ = scale; -} - -base::Closure OffScreenWindow::PrepareForLayerBoundsChange() { - std::cout << "PrepareForLayerBoundsChange" << std::endl; - return base::Bind(&OffScreenWindow::OnBoundsChanged, base::Unretained(this)); -} - -void OffScreenWindow::OnBoundsChanged() { - std::cout << "OnBoundsChanged" << std::endl; -} - -void OffScreenWindow::OnSetNeedsBeginFrames(bool needs_begin_frames) { +void OffScreenWindow::OnSetNeedsBeginFrames(bool enabled) { std::cout << "OnSetNeedsBeginFrames" << std::endl; } -void OffScreenWindow::SendSwapCompositorFrame(cc::CompositorFrame* frame) { - std::cout << "SendSwapCompositorFrame" << std::endl; - std::vector messages_to_deliver_with_frame; - /*host_->Send(new ViewHostMsg_SwapCompositorFrame(host_->GetRoutingID(), - 10, *frame, messages_to_deliver_with_frame));*/ -} - } // namespace atom diff --git a/atom/browser/osr_window.h b/atom/browser/osr_window.h index ac5545f9a2..b00802c7f8 100644 --- a/atom/browser/osr_window.h +++ b/atom/browser/osr_window.h @@ -27,41 +27,85 @@ #include #include "ui/gfx/win/window_impl.h" +#include "content/browser/web_contents/web_contents_view.h" +#include "atom/browser/native_window_views.h" namespace atom { -class AtomCompositorHostWin : public gfx::WindowImpl { - public: - AtomCompositorHostWin() { - // Create a hidden 1x1 borderless window. - set_window_style(WS_POPUP | WS_SYSMENU); - Init(NULL, gfx::Rect(0, 0, 1, 1)); - } +class OffScreenWebContentsView : public content::WebContentsView { +public: + OffScreenWebContentsView(); + ~OffScreenWebContentsView(); - ~AtomCompositorHostWin() override { - DestroyWindow(hwnd()); - } + gfx::NativeView GetNativeView() const; + gfx::NativeView GetContentNativeView() const; + gfx::NativeWindow GetTopLevelNativeWindow() const; - private: - CR_BEGIN_MSG_MAP_EX(CompositorHostWin) - CR_MSG_WM_PAINT(OnPaint) - CR_END_MSG_MAP() + void GetContainerBounds(gfx::Rect* out) const; + void SizeContents(const gfx::Size& size); + void Focus(); + void SetInitialFocus(); + void StoreFocus(); + void RestoreFocus(); + content::DropData* GetDropData() const; + gfx::Rect GetViewBounds() const; - void OnPaint(HDC dc) { - ValidateRect(hwnd(), NULL); + void CreateView( + const gfx::Size& initial_size, gfx::NativeView context); + + content::RenderWidgetHostViewBase* CreateViewForWidget( + content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack); + content::RenderWidgetHostViewBase* CreateViewForPopupWidget( + content::RenderWidgetHost* render_widget_host); + + void SetPageTitle(const base::string16& title); + void RenderViewCreated(content::RenderViewHost* host); + void RenderViewSwappedIn(content::RenderViewHost* host); + void SetOverscrollControllerEnabled(bool enabled); +private: + content::RenderWidgetHostViewBase* view_; +}; + +class OffScreenOutputDevice : public cc::SoftwareOutputDevice { +public: + OffScreenOutputDevice(); + ~OffScreenOutputDevice(); + + + void saveSkBitmapToBMPFile(const SkBitmap& skBitmap, const char* path); + void Resize(const gfx::Size& pixel_size, float scale_factor) override; + SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override; + void EndPaint() override; + +private: + std::unique_ptr canvas_; + std::unique_ptr bitmap_; + gfx::Rect pending_damage_rect_; + + DISALLOW_COPY_AND_ASSIGN(OffScreenOutputDevice); +}; + +class AtomCompositorDelegate : public ui::CompositorDelegate { +public: + AtomCompositorDelegate() {}; + ~AtomCompositorDelegate() {}; + + std::unique_ptr CreateSoftwareOutputDevice( + ui::Compositor* compositor) { + return std::unique_ptr(new OffScreenOutputDevice); } }; class OffScreenWindow : public content::RenderWidgetHostViewBase, public content::DelegatedFrameHostClient, - public cc::BeginFrameObserver, - public ui::LayerDelegate, - public ui::LayerOwner { + public ui::CompositorDelegate { public: OffScreenWindow(content::RenderWidgetHost*); ~OffScreenWindow(); + void CreatePlatformWidget(); + //content::RenderWidgetHostView bool OnMessageReceived(const IPC::Message&) override; void InitAsChild(gfx::NativeView); @@ -87,6 +131,7 @@ public: bool GetScreenColorProfile(std::vector*); //content::RenderWidgetHostViewBase + void OnSwapCompositorFrame(uint32_t, std::unique_ptr); void ClearCompositorFrame(void); void InitAsPopup(content::RenderWidgetHostView *, const gfx::Rect &); void InitAsFullscreen(content::RenderWidgetHostView *); @@ -119,6 +164,8 @@ public: void UnlockCompositingSurface(void); void ImeCompositionRangeChanged( const gfx::Range &, const std::vector&); + gfx::Size GetPhysicalBackingSize() const override; + gfx::Size GetRequestedRendererSize() const override; //content::DelegatedFrameHostClient int DelegatedFrameHostGetGpuMemoryBufferClientId(void) const; @@ -137,70 +184,30 @@ public: void DelegatedFrameHostUpdateVSyncParameters( const base::TimeTicks &, const base::TimeDelta &); -//cc::BeginFrameObserver - void OnBeginFrame(const cc::BeginFrameArgs &); - const cc::BeginFrameArgs & LastUsedBeginFrameArgs(void) const; - void OnBeginFrameSourcePausedChanged(bool); - void AsValueInto(base::trace_event::TracedValue *) const; - - gfx::Size GetPhysicalBackingSize() const; - void UpdateScreenInfo(gfx::NativeView view); - gfx::Size GetRequestedRendererSize() const; - void OnSwapCompositorFrame(uint32_t, cc::CompositorFrame); - uint32_t SurfaceIdNamespaceAtPoint( - cc::SurfaceHittestDelegate* delegate, - const gfx::Point& point, - gfx::Point* transformed_point); - uint32_t GetSurfaceIdNamespace(); - - void OnPaintLayer(const ui::PaintContext &); - void OnDelegatedFrameDamage(const gfx::Rect &); - void OnDeviceScaleFactorChanged(float); - base::Closure PrepareForLayerBoundsChange(); - void OnBoundsChanged(); - - void OnSetNeedsBeginFrames(bool); - void SendSwapCompositorFrame(cc::CompositorFrame *); + std::unique_ptr CreateSoftwareOutputDevice( + ui::Compositor* compositor); + void OnSetNeedsBeginFrames(bool enabled); private: - content::RenderWidgetHostImpl* host_; - content::DelegatedFrameHost* delegated_frame_host_; + content::RenderWidgetHostImpl* render_widget_host_; + + std::unique_ptr delegated_frame_host_; + std::unique_ptr compositor_; + gfx::AcceleratedWidget compositor_widget_; + std::unique_ptr root_layer_; + + float scale_factor_; + bool is_showing_; gfx::Vector2dF last_scroll_offset_; - bool focus_; gfx::Size size_; - float scale_; - cc::BeginFrameSource* begin_frame_source_; - cc::BeginFrameArgs last_begin_frame_args_; - bool needs_begin_frames_; +#if defined(OS_WIN) + std::unique_ptr window_; +#endif - base::Thread* thread_; - ui::Compositor* compositor_; + base::WeakPtrFactory weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(OffScreenWindow); }; -class OffScreenOutputSurface : public cc::OutputSurface { -public: - OffScreenOutputSurface( - std::unique_ptr); - ~OffScreenOutputSurface(); - - void SwapBuffers(cc::CompositorFrame *); - bool BindToClient(cc::OutputSurfaceClient *); -}; - -class OffScreenOutputDevice : public cc::SoftwareOutputDevice { -public: - OffScreenOutputDevice(); - ~OffScreenOutputDevice(); - - void Resize(const gfx::Size& pixel_size, float scale_factor); - SkCanvas* BeginPaint(const gfx::Rect& damage_rect); - void EndPaint(); - void DiscardBackbuffer(); - void EnsureBackbuffer(); - gfx::VSyncProvider* GetVSyncProvider(); -}; - - } // namespace atom #endif // ATOM_BROWSER_OSR_WINDOW_H_ diff --git a/atom/browser/osr_window_win.cc b/atom/browser/osr_window_win.cc new file mode 100644 index 0000000000..1f42cd7136 --- /dev/null +++ b/atom/browser/osr_window_win.cc @@ -0,0 +1,41 @@ +// Copyright (c) 2013 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include + +#include "atom/browser/osr_window.h" + +namespace atom { + +class DummyWindowWin : public gfx::WindowImpl { +public: + DummyWindowWin() { + // Create a hidden 1x1 borderless window. + set_window_style(WS_POPUP | WS_SYSMENU); + Init(NULL, gfx::Rect(0, 0, 1, 1)); + } + + ~DummyWindowWin() override { + DestroyWindow(hwnd()); + } + +private: + CR_BEGIN_MSG_MAP_EX(DummyWindowWin) + CR_MSG_WM_PAINT(OnPaint) + CR_END_MSG_MAP() + + void OnPaint(HDC dc) { + ValidateRect(hwnd(), NULL); + } + + DISALLOW_COPY_AND_ASSIGN(DummyWindowWin); +}; + +void OffScreenWindow::CreatePlatformWidget() { + DCHECK(!window_); + window_.reset(new DummyWindowWin()); + compositor_widget_ = window_->hwnd(); +} + +} // namespace atom diff --git a/filenames.gypi b/filenames.gypi index 96eff4aa09..b0c0ff0e72 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -206,6 +206,7 @@ 'atom/browser/native_window_observer.h', 'atom/browser/osr_window.cc', 'atom/browser/osr_window.h', + 'atom/browser/osr_window_win.cc', 'atom/browser/net/asar/asar_protocol_handler.cc', 'atom/browser/net/asar/asar_protocol_handler.h', 'atom/browser/net/asar/url_request_asar_job.cc', From 50dc71d1c236be40117260d623314d33b01d05b3 Mon Sep 17 00:00:00 2001 From: gellert Date: Mon, 18 Jul 2016 16:16:23 +0200 Subject: [PATCH 3/8] gpu acclereted osr added --- atom/browser/api/atom_api_web_contents.cc | 24 +- atom/browser/api/atom_api_web_contents.h | 7 + atom/browser/api/frame_subscriber.cc | 3 +- atom/browser/common_web_contents_delegate.cc | 7 +- atom/browser/native_window_views.h | 6 +- atom/browser/osr_window.cc | 567 +++++++++++++++---- atom/browser/osr_window.h | 269 ++++++--- atom/browser/osr_window_mac.mm | 112 ++++ default_app/default_app.js | 4 + default_app/index.html | 8 + default_app/main.js | 2 +- filenames.gypi | 1 + 12 files changed, 812 insertions(+), 198 deletions(-) create mode 100644 atom/browser/osr_window_mac.mm diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 99cb2e0074..36b42ec78e 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1194,12 +1194,30 @@ void WebContents::BeginFrameSubscription(mate::Arguments* args) { const auto view = web_contents()->GetRenderWidgetHostView(); if (view) { - std::unique_ptr frame_subscriber(new FrameSubscriber( - isolate(), view, callback, only_dirty)); - view->BeginFrameSubscription(std::move(frame_subscriber)); + // std::unique_ptr frame_subscriber(new FrameSubscriber( + // isolate(), view, callback, only_dirty)); + // view->BeginFrameSubscription(std::move(frame_subscriber)); + paint_isolate_ = args->isolate(); + + auto v = static_cast(view); + paint_callback_ = base::Bind(&WebContents::OnPaint, + base::Unretained(this)); + v->SetPaintCallback(&paint_callback_); } } +void WebContents::OnPaint( + const gfx::Rect& damage_rect, + int bitmap_width, + int bitmap_height, + void* bitmap_pixels) { + + v8::MaybeLocal buffer = node::Buffer::New(paint_isolate_ + , (char *)bitmap_pixels, sizeof(bitmap_pixels)); + + Emit("paint", damage_rect, bitmap_width, bitmap_height, buffer.ToLocalChecked()); +} + void WebContents::EndFrameSubscription() { const auto view = web_contents()->GetRenderWidgetHostView(); if (view) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 2917aa860a..2d97a0146e 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -18,6 +18,8 @@ #include "native_mate/handle.h" #include "ui/gfx/image/image.h" +#include "atom/browser/osr_window.h" + namespace blink { struct WebDeviceEmulationParams; } @@ -141,6 +143,7 @@ class WebContents : public mate::TrackableObject, // Subscribe to the frame updates. void BeginFrameSubscription(mate::Arguments* args); void EndFrameSubscription(); + void OnPaint(const gfx::Rect&, int, int, void*); // Dragging native items. void StartDrag(const mate::Dictionary& item, mate::Arguments* args); @@ -279,6 +282,8 @@ class WebContents : public mate::TrackableObject, private: AtomBrowserContext* GetBrowserContext() const; + OffScreenWindow::OnPaintCallback paint_callback_; + uint32_t GetNextRequestId() { return ++request_id_; } @@ -299,6 +304,8 @@ class WebContents : public mate::TrackableObject, v8::Global devtools_web_contents_; v8::Global debugger_; + v8::Isolate* paint_isolate_; + std::unique_ptr guest_delegate_; // The host webcontents that may contain this webcontents. diff --git a/atom/browser/api/frame_subscriber.cc b/atom/browser/api/frame_subscriber.cc index 456a535d60..b8bfae2241 100644 --- a/atom/browser/api/frame_subscriber.cc +++ b/atom/browser/api/frame_subscriber.cc @@ -74,7 +74,8 @@ bool FrameSubscriber::ShouldCaptureFrame( base::Bind(&FrameSubscriber::ReadbackResultAsBitmap, base::Unretained(this))); - surface->RequestCopyOfOutput(std::move(request)); + // surface->RequestCopyOfOutput(std::move(request)); + std::cout << request.get() << surface << std::endl; return false; } diff --git a/atom/browser/common_web_contents_delegate.cc b/atom/browser/common_web_contents_delegate.cc index 80a9bc211b..0b59d513d4 100644 --- a/atom/browser/common_web_contents_delegate.cc +++ b/atom/browser/common_web_contents_delegate.cc @@ -191,11 +191,12 @@ void CommonWebContentsDelegate::InitWithWebContents( content::WebContentsImpl* impl = reinterpret_cast(web_contents); - impl->SetView(new OffScreenWebContentsView); std::cout << "end" << std::endl; // Create InspectableWebContents. - /*web_contents_.reset(brightray::InspectableWebContents::Create(web_contents)); - web_contents_->SetDelegate(this);*/ + web_contents_.reset(brightray::InspectableWebContents::Create(web_contents)); + web_contents_->SetDelegate(this); + + impl->SetView(new OffScreenWebContentsView); std::cout << "end" << std::endl; } diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index a3bea9b97a..a4ea107194 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -171,9 +171,9 @@ class NativeWindowViews : public NativeWindow, content::WebContents*, const content::NativeWebKeyboardEvent& event) override; - // views::View: - gfx::Size GetMinimumSize() override; - gfx::Size GetMaximumSize() override; + // // views::View: + // gfx::Size GetMinimumSize() const override; + // gfx::Size GetMaximumSize() const override; bool AcceleratorPressed(const ui::Accelerator& accelerator) override; // Register accelerators supported by the menu model. diff --git a/atom/browser/osr_window.cc b/atom/browser/osr_window.cc index ed4eeb691e..2676c5350b 100644 --- a/atom/browser/osr_window.cc +++ b/atom/browser/osr_window.cc @@ -4,6 +4,7 @@ #include "atom/browser/osr_window.h" #include "third_party/WebKit/public/platform/WebScreenInfo.h" +#include "content/browser/compositor/gl_helper.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_delegate.h" #include "content/public/browser/render_widget_host_view_frame_subscriber.h" @@ -24,6 +25,31 @@ #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/core/SkPixmap.h" #include "cc/output/output_surface_client.h" +#include "cc/output/copy_output_request.h" + +#include "base/callback_helpers.h" +#include "base/location.h" +#include "base/logging.h" +#include "content/public/browser/browser_thread.h" +#include "cc/scheduler/delay_based_time_source.h" + +// const float kDefaultScaleFactor = 1.0; + +// The maximum number of retry counts if frame capture fails. +const int kFrameRetryLimit = 2; + +// When accelerated compositing is enabled and a widget resize is pending, +// we delay further resizes of the UI. The following constant is the maximum +// length of time that we should delay further UI resizes while waiting for a +// resized frame from a renderer. +// const int kResizeLockTimeoutMs = 67; + +#define CEF_UIT content::BrowserThread::UI +#define CEF_POST_TASK(id, task) \ + content::BrowserThread::PostTask(id, FROM_HERE, task) +#define CEF_POST_DELAYED_TASK(id, task, delay_ms) \ + content::BrowserThread::PostDelayedTask(id, FROM_HERE, task, \ + base::TimeDelta::FromMilliseconds(delay_ms)) namespace atom { @@ -166,10 +192,21 @@ void OffScreenWebContentsView::SetOverscrollControllerEnabled(bool enabled){ std::cout << "SetOverscrollControllerEnabled" << std::endl; } +#if defined(OS_MACOSX) +void OffScreenWebContentsView::SetAllowOtherViews(bool allow) { +} +bool OffScreenWebContentsView::GetAllowOtherViews() const { + return false; +} +bool OffScreenWebContentsView::IsEventTracking() const { + return false; +} - +void OffScreenWebContentsView::CloseTabAfterEventTracking() { +} +#endif // defined(OS_MACOSX) OffScreenOutputDevice::OffScreenOutputDevice() { std::cout << "OffScreenOutputDevice" << std::endl; @@ -215,99 +252,6 @@ SkCanvas* OffScreenOutputDevice::BeginPaint(const gfx::Rect& damage_rect) { return canvas_.get(); } -void OffScreenOutputDevice::saveSkBitmapToBMPFile(const SkBitmap& skBitmap, const char* path){ - typedef unsigned char UINT8; - typedef signed char SINT8; - typedef unsigned short UINT16; - typedef signed short SINT16; - typedef unsigned int UINT32; - typedef signed int SINT32; - - struct BMP_FILEHDR // BMP file header - { - UINT32 bfSize; // size of file - UINT16 bfReserved1; - UINT16 bfReserved2; - UINT32 bfOffBits; // pointer to the pixmap bits - }; - - struct BMP_INFOHDR // BMP information header - { - UINT32 biSize; // size of this struct - UINT32 biWidth; // pixmap width - UINT32 biHeight; // pixmap height - UINT16 biPlanes; // should be 1 - UINT16 biBitCount; // number of bits per pixel - UINT32 biCompression; // compression method - UINT32 biSizeImage; // size of image - UINT32 biXPelsPerMeter; // horizontal resolution - UINT32 biYPelsPerMeter; // vertical resolution - UINT32 biClrUsed; // number of colors used - UINT32 biClrImportant; // number of important colors - }; - #define BitmapColorGetA(color) (((color) >> 24) & 0xFF) - #define BitmapColorGetR(color) (((color) >> 16) & 0xFF) - #define BitmapColorGetG(color) (((color) >> 8) & 0xFF) - #define BitmapColorGetB(color) (((color) >> 0) & 0xFF) - - int bmpWidth = skBitmap.width(); - int bmpHeight = skBitmap.height(); - int stride = skBitmap.rowBytes(); - char* m_pmap = (char*)skBitmap.getPixels(); - //virtual PixelFormat& GetPixelFormat() =0; //assume pf is ARGB; - FILE* fp = fopen(path, "wb"); - if(!fp){ - printf("saveSkBitmapToBMPFile: fopen %s Error!\n", path); - } - SINT32 bpl=bmpWidth*4; - // BMP file header. - BMP_FILEHDR fhdr; - fputc('B', fp); - fputc('M', fp); - fhdr.bfReserved1=fhdr.bfReserved2=0; - fhdr.bfOffBits=14+40; // File header size + header size. - fhdr.bfSize=fhdr.bfOffBits+bpl*bmpHeight; - fwrite(&fhdr, 1, 12, fp); - - // BMP header. - BMP_INFOHDR bhdr; - bhdr.biSize=40; - bhdr.biBitCount=32; - bhdr.biCompression=0; // RGB Format. - bhdr.biPlanes=1; - bhdr.biWidth=bmpWidth; - bhdr.biHeight=bmpHeight; - bhdr.biClrImportant=0; - bhdr.biClrUsed=0; - bhdr.biXPelsPerMeter=2384; - bhdr.biYPelsPerMeter=2384; - bhdr.biSizeImage=bpl*bmpHeight; - fwrite(&bhdr, 1, 40, fp); - - // BMP data. - //for(UINT32 y=0; y=0; y--) - { - SINT32 base=y*stride; - for(SINT32 x=0; x<(SINT32)bmpWidth; x++) - { - UINT32 i=base+x*4; - UINT32 pixelData = *(UINT32*)(m_pmap+i); - UINT8 b1=BitmapColorGetB(pixelData); - UINT8 g1=BitmapColorGetG(pixelData); - UINT8 r1=BitmapColorGetR(pixelData); - UINT8 a1=BitmapColorGetA(pixelData); - r1=r1*a1/255; - g1=g1*a1/255; - b1=b1*a1/255; - UINT32 temp=(a1<<24)|(r1<<16)|(g1<<8)|b1;//a bmp pixel in little endian is B、G、R、A - fwrite(&temp, 4, 1, fp); - } - } - fflush(fp); - fclose(fp); -} - void OffScreenOutputDevice::EndPaint() { std::cout << "EndPaint" << std::endl; @@ -322,19 +266,351 @@ void OffScreenOutputDevice::EndPaint() { //saveSkBitmapToBMPFile(*(bitmap_.get()), "test.bmp"); uint8_t* pixels = reinterpret_cast(bitmap_->getPixels()); - for (int i = 0; i<4; i++) { + for (int i = 0; i<16; i++) { int x = static_cast(pixels[i]); std::cout << std::hex << x << std::dec << std::endl; } } +// Used for managing copy requests when GPU compositing is enabled. Based on +// RendererOverridesHandler::InnerSwapCompositorFrame and +// DelegatedFrameHost::CopyFromCompositingSurface. +class CefCopyFrameGenerator { + public: + CefCopyFrameGenerator(int frame_rate_threshold_ms, + OffScreenWindow* view) + : frame_rate_threshold_ms_(frame_rate_threshold_ms), + view_(view), + frame_pending_(false), + frame_in_progress_(false), + frame_retry_count_(0), + weak_ptr_factory_(this) { + } + + void GenerateCopyFrame( + bool force_frame, + const gfx::Rect& damage_rect) { + if (force_frame && !frame_pending_) + frame_pending_ = true; + + // No frame needs to be generated at this time. + if (!frame_pending_) + return; + + // Keep track of |damage_rect| for when the next frame is generated. + if (!damage_rect.IsEmpty()) + pending_damage_rect_.Union(damage_rect); + + // Don't attempt to generate a frame while one is currently in-progress. + if (frame_in_progress_) + return; + frame_in_progress_ = true; + + // Don't exceed the frame rate threshold. + const int64_t frame_rate_delta = + (base::TimeTicks::Now() - frame_start_time_).InMilliseconds(); + if (frame_rate_delta < frame_rate_threshold_ms_) { + // Generate the frame after the necessary time has passed. + CEF_POST_DELAYED_TASK(CEF_UIT, + base::Bind(&CefCopyFrameGenerator::InternalGenerateCopyFrame, + weak_ptr_factory_.GetWeakPtr()), + frame_rate_threshold_ms_ - frame_rate_delta); + return; + } + + InternalGenerateCopyFrame(); + } + + bool frame_pending() const { return frame_pending_; } + + void set_frame_rate_threshold_ms(int frame_rate_threshold_ms) { + frame_rate_threshold_ms_ = frame_rate_threshold_ms; + } + + private: + void InternalGenerateCopyFrame() { + frame_pending_ = false; + frame_start_time_ = base::TimeTicks::Now(); + + if (!view_->render_widget_host()) + return; + + const gfx::Rect damage_rect = pending_damage_rect_; + pending_damage_rect_.SetRect(0, 0, 0, 0); + + // The below code is similar in functionality to + // DelegatedFrameHost::CopyFromCompositingSurface but we reuse the same + // SkBitmap in the GPU codepath and avoid scaling where possible. + std::unique_ptr request = + cc::CopyOutputRequest::CreateRequest(base::Bind( + &CefCopyFrameGenerator::CopyFromCompositingSurfaceHasResult, + weak_ptr_factory_.GetWeakPtr(), + gfx::Rect(view_->GetPhysicalBackingSize()))); + + // request->set_area(gfx::Rect(view_->GetPhysicalBackingSize())); + + view_->DelegatedFrameHostGetLayer()->RequestCopyOfOutput( + std::move(request)); + } + + void CopyFromCompositingSurfaceHasResult( + const gfx::Rect& damage_rect, + std::unique_ptr result) { + std::cout << "has result" << std::endl; + if (result->IsEmpty() || result->size().IsEmpty() || + !view_->render_widget_host()) { + OnCopyFrameCaptureFailure(damage_rect); + return; + } + + if (result->HasTexture()) { + PrepareTextureCopyOutputResult(damage_rect, std::move(result)); + return; + } + + DCHECK(result->HasBitmap()); + PrepareBitmapCopyOutputResult(damage_rect, std::move(result)); + } + + void PrepareTextureCopyOutputResult( + const gfx::Rect& damage_rect, + std::unique_ptr result) { + DCHECK(result->HasTexture()); + base::ScopedClosureRunner scoped_callback_runner( + base::Bind(&CefCopyFrameGenerator::OnCopyFrameCaptureFailure, + weak_ptr_factory_.GetWeakPtr(), + damage_rect)); + + const gfx::Size& result_size = result->size(); + SkIRect bitmap_size; + if (bitmap_) + bitmap_->getBounds(&bitmap_size); + + if (!bitmap_ || + bitmap_size.width() != result_size.width() || + bitmap_size.height() != result_size.height()) { + // Create a new bitmap if the size has changed. + bitmap_.reset(new SkBitmap); + bitmap_->allocN32Pixels(result_size.width(), + result_size.height(), + true); + if (bitmap_->drawsNothing()) + return; + } + + content::ImageTransportFactory* factory = + content::ImageTransportFactory::GetInstance(); + content::GLHelper* gl_helper = factory->GetGLHelper(); + if (!gl_helper) + return; + + std::unique_ptr bitmap_pixels_lock( + new SkAutoLockPixels(*bitmap_)); + uint8_t* pixels = static_cast(bitmap_->getPixels()); + + cc::TextureMailbox texture_mailbox; + std::unique_ptr release_callback; + result->TakeTexture(&texture_mailbox, &release_callback); + DCHECK(texture_mailbox.IsTexture()); + if (!texture_mailbox.IsTexture()) + return; + + ignore_result(scoped_callback_runner.Release()); + + gl_helper->CropScaleReadbackAndCleanMailbox( + texture_mailbox.mailbox(), + texture_mailbox.sync_token(), + result_size, + gfx::Rect(result_size), + result_size, + pixels, + kN32_SkColorType, + base::Bind( + &CefCopyFrameGenerator::CopyFromCompositingSurfaceFinishedProxy, + weak_ptr_factory_.GetWeakPtr(), + base::Passed(&release_callback), + damage_rect, + base::Passed(&bitmap_), + base::Passed(&bitmap_pixels_lock)), + content::GLHelper::SCALER_QUALITY_FAST); + } + + static void CopyFromCompositingSurfaceFinishedProxy( + base::WeakPtr generator, + std::unique_ptr release_callback, + const gfx::Rect& damage_rect, + std::unique_ptr bitmap, + std::unique_ptr bitmap_pixels_lock, + bool result) { + // This method may be called after the view has been deleted. + gpu::SyncToken sync_token; + if (result) { + content::GLHelper* gl_helper = + content::ImageTransportFactory::GetInstance()->GetGLHelper(); + if (gl_helper) + gl_helper->GenerateSyncToken(&sync_token); + } + const bool lost_resource = !sync_token.HasData(); + release_callback->Run(sync_token, lost_resource); + + if (generator) { + generator->CopyFromCompositingSurfaceFinished( + damage_rect, std::move(bitmap), std::move(bitmap_pixels_lock), + result); + } else { + bitmap_pixels_lock.reset(); + bitmap.reset(); + } + } + + void CopyFromCompositingSurfaceFinished( + const gfx::Rect& damage_rect, + std::unique_ptr bitmap, + std::unique_ptr bitmap_pixels_lock, + bool result) { + // Restore ownership of the bitmap to the view. + DCHECK(!bitmap_); + bitmap_ = std::move(bitmap); + + if (result) { + OnCopyFrameCaptureSuccess(damage_rect, *bitmap_, + std::move(bitmap_pixels_lock)); + } else { + bitmap_pixels_lock.reset(); + OnCopyFrameCaptureFailure(damage_rect); + } + } + + void PrepareBitmapCopyOutputResult( + const gfx::Rect& damage_rect, + std::unique_ptr result) { + DCHECK(result->HasBitmap()); + std::unique_ptr source = result->TakeBitmap(); + DCHECK(source); + if (source) { + std::unique_ptr bitmap_pixels_lock( + new SkAutoLockPixels(*source)); + OnCopyFrameCaptureSuccess(damage_rect, *source, + std::move(bitmap_pixels_lock)); + } else { + OnCopyFrameCaptureFailure(damage_rect); + } + } + + void OnCopyFrameCaptureFailure( + const gfx::Rect& damage_rect) { + // Retry with the same |damage_rect|. + pending_damage_rect_.Union(damage_rect); + + const bool force_frame = (++frame_retry_count_ <= kFrameRetryLimit); + OnCopyFrameCaptureCompletion(force_frame); + } + + void OnCopyFrameCaptureSuccess( + const gfx::Rect& damage_rect, + const SkBitmap& bitmap, + std::unique_ptr bitmap_pixels_lock) { + + + // view_->OnPaint(damage_rect, bitmap.width(), bitmap.height(), + // bitmap.getPixels()); + + uint8_t* pixels = reinterpret_cast(bitmap.getPixels()); + for (int i = 0; i<4; i++) { + int x = static_cast(pixels[i]); + std::cout << std::hex << x << std::dec << std::endl; + } + if (view_->paintCallback) { + std::cout << "FRAME COPY ARRIVED" << std::endl; + view_->paintCallback->Run(damage_rect, bitmap.width(), bitmap.height(), + pixels); + } + + bitmap_pixels_lock.reset(); + + // Reset the frame retry count on successful frame generation. + if (frame_retry_count_ > 0) + frame_retry_count_ = 0; + + OnCopyFrameCaptureCompletion(false); + } + + void OnCopyFrameCaptureCompletion(bool force_frame) { + frame_in_progress_ = false; + + if (frame_pending_) { + // Another frame was requested while the current frame was in-progress. + // Generate the pending frame now. + CEF_POST_TASK(CEF_UIT, + base::Bind(&CefCopyFrameGenerator::GenerateCopyFrame, + weak_ptr_factory_.GetWeakPtr(), + force_frame, + gfx::Rect())); + } + } + + int frame_rate_threshold_ms_; + OffScreenWindow* view_; + + base::TimeTicks frame_start_time_; + bool frame_pending_; + bool frame_in_progress_; + int frame_retry_count_; + std::unique_ptr bitmap_; + gfx::Rect pending_damage_rect_; + + base::WeakPtrFactory weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(CefCopyFrameGenerator); +}; + +// Used to control the VSync rate in subprocesses when BeginFrame scheduling is +// enabled. +class CefBeginFrameTimer : public cc::DelayBasedTimeSourceClient { + public: + CefBeginFrameTimer(int frame_rate_threshold_ms, + const base::Closure& callback) + : callback_(callback) { + time_source_ = cc::DelayBasedTimeSource::Create( + base::TimeDelta::FromMilliseconds(frame_rate_threshold_ms), + content::BrowserThread::GetMessageLoopProxyForThread(CEF_UIT).get()); + time_source_->SetClient(this); + } + + void SetActive(bool active) { + time_source_->SetActive(active); + } + + bool IsActive() const { + return time_source_->Active(); + } + + void SetFrameRateThresholdMs(int frame_rate_threshold_ms) { + time_source_->SetTimebaseAndInterval( + base::TimeTicks::Now(), + base::TimeDelta::FromMilliseconds(frame_rate_threshold_ms)); + } + + private: + // cc::TimerSourceClient implementation. + void OnTimerTick() override { + callback_.Run(); + } + + const base::Closure callback_; + std::unique_ptr time_source_; + + DISALLOW_COPY_AND_ASSIGN(CefBeginFrameTimer); +}; + OffScreenWindow::OffScreenWindow(content::RenderWidgetHost* host) : render_widget_host_(content::RenderWidgetHostImpl::From(host)), - delegated_frame_host_(new content::DelegatedFrameHost(this)), - compositor_widget_(gfx::kNullAcceleratedWidget), + frame_rate_threshold_ms_(0), scale_factor_(1.0f), is_showing_(!render_widget_host_->is_hidden()), size_(gfx::Size(800, 600)), + delegated_frame_host_(new content::DelegatedFrameHost(this)), + compositor_widget_(gfx::kNullAcceleratedWidget), weak_ptr_factory_(this) { DCHECK(render_widget_host_); std::cout << "OffScreenWindow" << std::endl; @@ -344,16 +620,61 @@ OffScreenWindow::OffScreenWindow(content::RenderWidgetHost* host) CreatePlatformWidget(); - compositor_.reset(new ui::Compositor(content::GetContextFactory(), - base::ThreadTaskRunnerHandle::Get())); +#if !defined(OS_MACOSX) + // On OS X the ui::Compositor is created/owned by the platform view. + compositor_.reset( + new ui::Compositor(content::GetContextFactory(), + base::ThreadTaskRunnerHandle::Get())); compositor_->SetAcceleratedWidget(compositor_widget_); - compositor_->SetDelegate(this); +#endif + // compositor_->SetDelegate(this); compositor_->SetRootLayer(root_layer_.get()); + + frame_rate_threshold_ms_ = 1000 / 24; + begin_frame_timer_.reset(new CefBeginFrameTimer( + frame_rate_threshold_ms_, + base::Bind(&OffScreenWindow::OnBeginFrameTimerTick, + weak_ptr_factory_.GetWeakPtr()))); + + // begin_frame_timer_->SetActive(true); +} + +void OffScreenWindow::OnBeginFrameTimerTick() { + const base::TimeTicks frame_time = base::TimeTicks::Now(); + const base::TimeDelta vsync_period = + base::TimeDelta::FromMilliseconds(frame_rate_threshold_ms_); + SendBeginFrame(frame_time, vsync_period); + + std::cout << "tickkkk" << std::endl; + // copy_frame_generator_->GenerateCopyFrame(true, damage_rect); +} + +void OffScreenWindow::SendBeginFrame(base::TimeTicks frame_time, + base::TimeDelta vsync_period) { + base::TimeTicks display_time = frame_time + vsync_period; + + // TODO(brianderson): Use adaptive draw-time estimation. + base::TimeDelta estimated_browser_composite_time = + base::TimeDelta::FromMicroseconds( + (1.0f * base::Time::kMicrosecondsPerSecond) / (3.0f * 60)); + + base::TimeTicks deadline = display_time - estimated_browser_composite_time; + + render_widget_host_->Send(new ViewMsg_BeginFrame( + render_widget_host_->GetRoutingID(), + cc::BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, deadline, + vsync_period, cc::BeginFrameArgs::NORMAL))); +} + +void OffScreenWindow::SetPaintCallback(const OnPaintCallback *callback) { + paintCallback.reset(callback); } OffScreenWindow::~OffScreenWindow() { std::cout << "~OffScreenWindow" << std::endl; - if (is_showing_) delegated_frame_host_->WasHidden(); + + if (is_showing_) + delegated_frame_host_->WasHidden(); delegated_frame_host_->ResetCompositor(); delegated_frame_host_.reset(NULL); @@ -447,7 +768,8 @@ void OffScreenWindow::Show() { return; is_showing_ = true; - if (render_widget_host_) render_widget_host_->WasShown(ui::LatencyInfo()); + if (render_widget_host_) + render_widget_host_->WasShown(ui::LatencyInfo()); delegated_frame_host_->SetCompositor(compositor_.get()); delegated_frame_host_->WasShown(ui::LatencyInfo()); } @@ -457,7 +779,8 @@ void OffScreenWindow::Hide() { if (!is_showing_) return; - if (render_widget_host_) render_widget_host_->WasHidden(); + if (render_widget_host_) + render_widget_host_->WasHidden(); delegated_frame_host_->WasHidden(); delegated_frame_host_->ResetCompositor(); is_showing_ = false; @@ -512,9 +835,43 @@ void OffScreenWindow::OnSwapCompositorFrame( last_scroll_offset_ = frame->metadata.root_scroll_offset; } + if (!copy_frame_generator_.get()) { + copy_frame_generator_.reset( + new CefCopyFrameGenerator(frame_rate_threshold_ms_, this)); + } + + // Determine the damage rectangle for the current frame. This is the same + // calculation that SwapDelegatedFrame uses. + // cc::RenderPass* root_pass = + // frame->delegated_frame_data->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)); + gfx::Rect damage_rect = gfx::Rect(GetVisibleViewportSize()); + if (frame->delegated_frame_data) - delegated_frame_host_->SwapDelegatedFrame( - output_surface_id, std::move(frame)); + delegated_frame_host_->SwapDelegatedFrame(output_surface_id, + std::move(frame)); + + // Request a copy of the last compositor frame which will eventually call + // OnPaint asynchronously. + std::cout << "FRAME COPY REQUESTED" << std::endl; + copy_frame_generator_->GenerateCopyFrame(true, damage_rect); + + // gfx::Rect rect = gfx::Rect(GetVisibleViewportSize()); + // // The below code is similar in functionality to + // // DelegatedFrameHost::CopyFromCompositingSurface but we reuse the same + // // SkBitmap in the GPU codepath and avoid scaling where possible. + // std::unique_ptr request = + // cc::CopyOutputRequest::CreateRequest(base::Bind( + // &OffScreenWindow::CopyFromCompositingSurfaceHasResult, + // weak_ptr_factory_.GetWeakPtr(), + // rect)); + // + // request->set_area(gfx::Rect(GetPhysicalBackingSize())); + // DelegatedFrameHostGetLayer()->RequestCopyOfOutput( + // std::move(request)); } void OffScreenWindow::ClearCompositorFrame() { diff --git a/atom/browser/osr_window.h b/atom/browser/osr_window.h index b00802c7f8..d566cdda46 100644 --- a/atom/browser/osr_window.h +++ b/atom/browser/osr_window.h @@ -25,43 +25,78 @@ #include "cc/output/output_surface_client.h" #include "cc/scheduler/begin_frame_source.h" +#include "content/browser/web_contents/web_contents_view.h" +// #include "atom/browser/native_window_views.h" + +#if defined(OS_WIN) #include #include "ui/gfx/win/window_impl.h" -#include "content/browser/web_contents/web_contents_view.h" -#include "atom/browser/native_window_views.h" +#endif + +#if defined(OS_MACOSX) +#include "content/browser/renderer_host/browser_compositor_view_mac.h" +#include "ui/accelerated_widget_mac/accelerated_widget_mac.h" +#endif + +#if defined(OS_MACOSX) +#ifdef __OBJC__ +@class CALayer; +@class NSWindow; +@class NSTextInputContext; +#else +class CALayer; +class NSWindow; +class NSTextInputContext; +#endif +#endif + +#if defined(OS_MACOSX) +class AcceleratedWidgetMacNSViewHelper; +#endif namespace atom { +class CefCopyFrameGenerator; +class CefBeginFrameTimer; + class OffScreenWebContentsView : public content::WebContentsView { public: OffScreenWebContentsView(); ~OffScreenWebContentsView(); - gfx::NativeView GetNativeView() const; - gfx::NativeView GetContentNativeView() const; - gfx::NativeWindow GetTopLevelNativeWindow() const; + gfx::NativeView GetNativeView() const override; + gfx::NativeView GetContentNativeView() const override; + gfx::NativeWindow GetTopLevelNativeWindow() const override; - void GetContainerBounds(gfx::Rect* out) const; - void SizeContents(const gfx::Size& size); - void Focus(); - void SetInitialFocus(); - void StoreFocus(); - void RestoreFocus(); - content::DropData* GetDropData() const; - gfx::Rect GetViewBounds() const; + void GetContainerBounds(gfx::Rect* out) const override; + void SizeContents(const gfx::Size& size) override; + void Focus() override; + void SetInitialFocus() override; + void StoreFocus() override; + void RestoreFocus() override; + content::DropData* GetDropData() const override; + gfx::Rect GetViewBounds() const override; void CreateView( - const gfx::Size& initial_size, gfx::NativeView context); + const gfx::Size& initial_size, gfx::NativeView context) override; content::RenderWidgetHostViewBase* CreateViewForWidget( - content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack); + content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack) override; content::RenderWidgetHostViewBase* CreateViewForPopupWidget( - content::RenderWidgetHost* render_widget_host); + content::RenderWidgetHost* render_widget_host) override; + + void SetPageTitle(const base::string16& title) override; + void RenderViewCreated(content::RenderViewHost* host) override; + void RenderViewSwappedIn(content::RenderViewHost* host) override; + void SetOverscrollControllerEnabled(bool enabled) override; + +#if defined(OS_MACOSX) + void SetAllowOtherViews(bool allow) override; + bool GetAllowOtherViews() const override; + bool IsEventTracking() const override; + void CloseTabAfterEventTracking() override; +#endif - void SetPageTitle(const base::string16& title); - void RenderViewCreated(content::RenderViewHost* host); - void RenderViewSwappedIn(content::RenderViewHost* host); - void SetOverscrollControllerEnabled(bool enabled); private: content::RenderWidgetHostViewBase* view_; }; @@ -72,7 +107,7 @@ public: ~OffScreenOutputDevice(); - void saveSkBitmapToBMPFile(const SkBitmap& skBitmap, const char* path); + // void saveSkBitmapToBMPFile(const SkBitmap& skBitmap, const char* path); void Resize(const gfx::Size& pixel_size, float scale_factor) override; SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override; void EndPaint() override; @@ -91,16 +126,22 @@ public: ~AtomCompositorDelegate() {}; std::unique_ptr CreateSoftwareOutputDevice( - ui::Compositor* compositor) { + ui::Compositor* compositor) override { return std::unique_ptr(new OffScreenOutputDevice); } }; class OffScreenWindow - : public content::RenderWidgetHostViewBase, - public content::DelegatedFrameHostClient, - public ui::CompositorDelegate { + : public content::RenderWidgetHostViewBase, + #if defined(OS_MACOSX) + public ui::AcceleratedWidgetMacNSView, + #endif + public ui::CompositorDelegate, + public content::DelegatedFrameHostClient { public: + typedef base::Callback + OnPaintCallback; + OffScreenWindow(content::RenderWidgetHost*); ~OffScreenWindow(); @@ -108,100 +149,164 @@ public: //content::RenderWidgetHostView bool OnMessageReceived(const IPC::Message&) override; - void InitAsChild(gfx::NativeView); - content::RenderWidgetHost* GetRenderWidgetHost(void) const; - void SetSize(const gfx::Size &); - void SetBounds(const gfx::Rect &); - gfx::Vector2dF GetLastScrollOffset(void) const; - gfx::NativeView GetNativeView(void) const; - gfx::NativeViewId GetNativeViewId(void) const; - gfx::NativeViewAccessible GetNativeViewAccessible(void); + void InitAsChild(gfx::NativeView) override; + content::RenderWidgetHost* GetRenderWidgetHost(void) const override; + void SetSize(const gfx::Size &) override; + void SetBounds(const gfx::Rect &) override; + gfx::Vector2dF GetLastScrollOffset(void) const override; + gfx::NativeView GetNativeView(void) const override; + gfx::NativeViewId GetNativeViewId(void) const override; + gfx::NativeViewAccessible GetNativeViewAccessible(void) override; ui::TextInputClient* GetTextInputClient() override; - void Focus(void); - bool HasFocus(void) const; - bool IsSurfaceAvailableForCopy(void) const; - void Show(void); - void Hide(void); - bool IsShowing(void); - gfx::Rect GetViewBounds(void) const; + void Focus(void) override; + bool HasFocus(void) const override; + bool IsSurfaceAvailableForCopy(void) const override; + void Show(void) override; + void Hide(void) override; + bool IsShowing(void) override; + gfx::Rect GetViewBounds(void) const override; gfx::Size GetVisibleViewportSize() const override; void SetInsets(const gfx::Insets&) override; - bool LockMouse(void); - void UnlockMouse(void); - bool GetScreenColorProfile(std::vector*); + bool LockMouse(void) override; + void UnlockMouse(void) override; + bool GetScreenColorProfile(std::vector*) override; + +#if defined(OS_MACOSX) + void SetActive(bool active) override; + void ShowDefinitionForSelection() override; + bool SupportsSpeech() const override; + void SpeakSelection() override; + bool IsSpeaking() const override; + void StopSpeaking() override; +#endif // defined(OS_MACOSX) //content::RenderWidgetHostViewBase - void OnSwapCompositorFrame(uint32_t, std::unique_ptr); - void ClearCompositorFrame(void); - void InitAsPopup(content::RenderWidgetHostView *, const gfx::Rect &); - void InitAsFullscreen(content::RenderWidgetHostView *); - void UpdateCursor(const content::WebCursor &); - void SetIsLoading(bool); - void TextInputStateChanged(const ViewHostMsg_TextInputState_Params &); - void ImeCancelComposition(void); - void RenderProcessGone(base::TerminationStatus,int); - void Destroy(void); - void SetTooltipText(const base::string16 &); - void SelectionBoundsChanged(const ViewHostMsg_SelectionBounds_Params &); + void OnSwapCompositorFrame(uint32_t, std::unique_ptr) override; + void ClearCompositorFrame(void) override; + void InitAsPopup(content::RenderWidgetHostView *, const gfx::Rect &) override; + void InitAsFullscreen(content::RenderWidgetHostView *) override; + void UpdateCursor(const content::WebCursor &) override; + void SetIsLoading(bool) override; + void TextInputStateChanged(const ViewHostMsg_TextInputState_Params &) override; + void ImeCancelComposition(void) override; + void RenderProcessGone(base::TerminationStatus,int) override; + void Destroy(void) override; + void SetTooltipText(const base::string16 &) override; + +#if defined(OS_MACOSX) + void SelectionChanged(const base::string16& text, + size_t offset, + const gfx::Range& range) override; +#endif + + void SelectionBoundsChanged(const ViewHostMsg_SelectionBounds_Params &) override; void CopyFromCompositingSurface(const gfx::Rect &, const gfx::Size &, const content::ReadbackRequestCallback &, - const SkColorType); + const SkColorType) override; void CopyFromCompositingSurfaceToVideoFrame( const gfx::Rect &, const scoped_refptr &, const base::Callback &); - bool CanCopyToVideoFrame(void) const; + base::internal::CopyMode::Copyable> &) override; + bool CanCopyToVideoFrame(void) const override; void BeginFrameSubscription( - std::unique_ptr); - void EndFrameSubscription(); - bool HasAcceleratedSurface(const gfx::Size &); - void GetScreenInfo(blink::WebScreenInfo *); + std::unique_ptr) override; + void EndFrameSubscription() override; + bool HasAcceleratedSurface(const gfx::Size &) override; + void GetScreenInfo(blink::WebScreenInfo *) override; bool GetScreenColorProfile(blink::WebVector*); - gfx::Rect GetBoundsInRootWindow(void); - void LockCompositingSurface(void); - void UnlockCompositingSurface(void); + gfx::Rect GetBoundsInRootWindow(void) override; + void LockCompositingSurface(void) override; + void UnlockCompositingSurface(void) override; void ImeCompositionRangeChanged( - const gfx::Range &, const std::vector&); + const gfx::Range &, const std::vector&) override; gfx::Size GetPhysicalBackingSize() const override; gfx::Size GetRequestedRendererSize() const override; //content::DelegatedFrameHostClient int DelegatedFrameHostGetGpuMemoryBufferClientId(void) const; - ui::Layer *DelegatedFrameHostGetLayer(void) const; - bool DelegatedFrameHostIsVisible(void) const; - SkColor DelegatedFrameHostGetGutterColor(SkColor) const; - gfx::Size DelegatedFrameHostDesiredSizeInDIP(void) const; - bool DelegatedFrameCanCreateResizeLock(void) const; - std::unique_ptr DelegatedFrameHostCreateResizeLock(bool); - void DelegatedFrameHostResizeLockWasReleased(void); + ui::Layer *DelegatedFrameHostGetLayer(void) const override; + bool DelegatedFrameHostIsVisible(void) const override; + SkColor DelegatedFrameHostGetGutterColor(SkColor) const override; + gfx::Size DelegatedFrameHostDesiredSizeInDIP(void) const override; + bool DelegatedFrameCanCreateResizeLock(void) const override; + std::unique_ptr DelegatedFrameHostCreateResizeLock(bool) override; + void DelegatedFrameHostResizeLockWasReleased(void) override; void DelegatedFrameHostSendCompositorSwapAck( - int, const cc::CompositorFrameAck &); + int, const cc::CompositorFrameAck &) override; void DelegatedFrameHostSendReclaimCompositorResources( - int, const cc::CompositorFrameAck &); - void DelegatedFrameHostOnLostCompositorResources(void); + int, const cc::CompositorFrameAck &) override; + void DelegatedFrameHostOnLostCompositorResources(void) override; void DelegatedFrameHostUpdateVSyncParameters( - const base::TimeTicks &, const base::TimeDelta &); + const base::TimeTicks &, const base::TimeDelta &) override; std::unique_ptr CreateSoftwareOutputDevice( - ui::Compositor* compositor); + ui::Compositor* compositor) override; void OnSetNeedsBeginFrames(bool enabled); + +#if defined(OS_MACOSX) + // AcceleratedWidgetMacNSView implementation. + NSView* AcceleratedWidgetGetNSView() const override; + void AcceleratedWidgetGetVSyncParameters( + base::TimeTicks* timebase, base::TimeDelta* interval) const override; + void AcceleratedWidgetSwapCompleted() override; +#endif // defined(OS_MACOSX) + + ui::Compositor* compositor() const { return compositor_.get(); } + content::RenderWidgetHostImpl* render_widget_host() const + { return render_widget_host_; } + + void OnBeginFrameTimerTick(); + void SendBeginFrame(base::TimeTicks frame_time, + base::TimeDelta vsync_period); + + std::unique_ptr paintCallback; + void SetPaintCallback(const OnPaintCallback*); private: content::RenderWidgetHostImpl* render_widget_host_; - std::unique_ptr delegated_frame_host_; - std::unique_ptr compositor_; - gfx::AcceleratedWidget compositor_widget_; - std::unique_ptr root_layer_; + std::unique_ptr copy_frame_generator_; + std::unique_ptr begin_frame_timer_; + + int frame_rate_threshold_ms_; float scale_factor_; bool is_showing_; gfx::Vector2dF last_scroll_offset_; gfx::Size size_; + std::unique_ptr delegated_frame_host_; + std::unique_ptr compositor_; + gfx::AcceleratedWidget compositor_widget_; + std::unique_ptr root_layer_; + #if defined(OS_WIN) std::unique_ptr window_; +#elif defined(OS_MACOSX) + NSWindow* window_; + CALayer* background_layer_; + std::unique_ptr browser_compositor_; +#elif defined(USE_X11) + CefWindowX11* window_; + std::unique_ptr invisible_cursor_; +#endif + +#if defined(OS_MACOSX) + NSTextInputContext* text_input_context_osr_mac_; + + // Selected text on the renderer. + std::string selected_text_; + + // The current composition character range and its bounds. + gfx::Range composition_range_; + std::vector composition_bounds_; + + // The current caret bounds. + gfx::Rect caret_rect_; + + // The current first selection bounds. + gfx::Rect first_selection_rect_; #endif base::WeakPtrFactory weak_ptr_factory_; diff --git a/atom/browser/osr_window_mac.mm b/atom/browser/osr_window_mac.mm new file mode 100644 index 0000000000..0d806731ee --- /dev/null +++ b/atom/browser/osr_window_mac.mm @@ -0,0 +1,112 @@ +#include "atom/browser/osr_window.h" + +#include +#include +#include +#include + +#import + +#include "base/compiler_specific.h" +#include "base/strings/utf_string_conversions.h" +#include "content/common/view_messages.h" +#include "ui/accelerated_widget_mac/accelerated_widget_mac.h" +#include "ui/events/latency_info.h" + +NSView* atom::OffScreenWindow::AcceleratedWidgetGetNSView() const { + return [window_ contentView]; +} + +void atom::OffScreenWindow::AcceleratedWidgetGetVSyncParameters( + base::TimeTicks* timebase, base::TimeDelta* interval) const { + *timebase = base::TimeTicks(); + *interval = base::TimeDelta(); +} + +void atom::OffScreenWindow::AcceleratedWidgetSwapCompleted() { +} + +void atom::OffScreenWindow::SetActive(bool active) { +} + +void atom::OffScreenWindow::ShowDefinitionForSelection() { +} + +bool atom::OffScreenWindow::SupportsSpeech() const { + return false; +} + +void atom::OffScreenWindow::SpeakSelection() { +} + +bool atom::OffScreenWindow::IsSpeaking() const { + return false; +} + +void atom::OffScreenWindow::StopSpeaking() { +} + +void atom::OffScreenWindow::SelectionChanged( + const base::string16& text, + size_t offset, + const gfx::Range& range) { + if (range.is_empty() || text.empty()) { + selected_text_.clear(); + } else { + size_t pos = range.GetMin() - offset; + size_t n = range.length(); + + DCHECK(pos + n <= text.length()) << "The text can not fully cover range."; + if (pos >= text.length()) { + DCHECK(false) << "The text can not cover range."; + return; + } + selected_text_ = base::UTF16ToUTF8(text.substr(pos, n)); + } + + RenderWidgetHostViewBase::SelectionChanged(text, offset, range); +} + +void atom::OffScreenWindow::CreatePlatformWidget() { + // Create a borderless non-visible 1x1 window. + window_ = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 1, 1) + styleMask:NSBorderlessWindowMask + backing:NSBackingStoreBuffered + defer:NO]; + + // Create a CALayer which is used by BrowserCompositorViewMac for rendering. + background_layer_ = [[[CALayer alloc] init] retain]; + [background_layer_ setBackgroundColor:CGColorGetConstantColor(kCGColorClear)]; + NSView* content_view = [window_ contentView]; + [content_view setLayer:background_layer_]; + [content_view setWantsLayer:YES]; + + browser_compositor_ = content::BrowserCompositorMac::Create(); + + compositor_.reset(browser_compositor_->compositor()); + compositor_->SetRootLayer(root_layer_.get()); + browser_compositor_->accelerated_widget_mac()->SetNSView(this); + browser_compositor_->compositor()->SetVisible(true); + + // CEF needs the browser compositor to remain responsive whereas normal + // rendering on OS X does not. This effectively reverts the changes from + // https://crbug.com/463988#c6 + compositor_->SetLocksWillTimeOut(true); + browser_compositor_->Unsuspend(); +} + +// void atom::OffScreenWindow::PlatformDestroyCompositorWidget() { +// DCHECK(window_); +// +// browser_compositor_->Destroy(); +// +// [window_ close]; +// window_ = nil; +// [background_layer_ release]; +// background_layer_ = nil; +// +// browser_compositor_.reset(); +// +// delete accelerated_widget_helper_; +// accelerated_widget_helper_ = nullptr; +// } diff --git a/default_app/default_app.js b/default_app/default_app.js index 9f28872735..7515d6cbf5 100644 --- a/default_app/default_app.js +++ b/default_app/default_app.js @@ -23,5 +23,9 @@ exports.load = (appUrl) => { console.log("asd") }) }) + + mainWindow.webContents.on('paint', (e, rect, w, h, data) => { + console.log('ELECTRON EVENT', rect, w, h, data) + }) }) } diff --git a/default_app/index.html b/default_app/index.html index edfb3e6ddc..0c16fb1a91 100644 --- a/default_app/index.html +++ b/default_app/index.html @@ -129,6 +129,14 @@ e.preventDefault(); return false; }; + + document.onload = () => { + var a = false + setInterval(function () { + document.body.querySelector('.container').style.background = a ? 'red' : 'blue' + a = !a + }, 200) + }
diff --git a/default_app/main.js b/default_app/main.js index dd887e0def..a5359972bb 100644 --- a/default_app/main.js +++ b/default_app/main.js @@ -331,5 +331,5 @@ if (option.file && !option.webdriver) { startRepl() } else { const indexPath = path.join(__dirname, '/index.html') - loadApplicationByUrl(`file://${indexPath}`) + loadApplicationByUrl(`https://vimeo.com/channels/staffpicks/174711575#t=7s`) } diff --git a/filenames.gypi b/filenames.gypi index b0c0ff0e72..325b766030 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -207,6 +207,7 @@ 'atom/browser/osr_window.cc', 'atom/browser/osr_window.h', 'atom/browser/osr_window_win.cc', + 'atom/browser/osr_window_mac.mm', 'atom/browser/net/asar/asar_protocol_handler.cc', 'atom/browser/net/asar/asar_protocol_handler.h', 'atom/browser/net/asar/url_request_asar_job.cc', From 7fc9df4f8ff608467d5eccdac058fc06bfecd396 Mon Sep 17 00:00:00 2001 From: gellert Date: Tue, 19 Jul 2016 23:50:49 +0200 Subject: [PATCH 4/8] using damage_rect --- atom/browser/osr_window.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/atom/browser/osr_window.cc b/atom/browser/osr_window.cc index 2676c5350b..050315dfc3 100644 --- a/atom/browser/osr_window.cc +++ b/atom/browser/osr_window.cc @@ -345,7 +345,7 @@ class CefCopyFrameGenerator { cc::CopyOutputRequest::CreateRequest(base::Bind( &CefCopyFrameGenerator::CopyFromCompositingSurfaceHasResult, weak_ptr_factory_.GetWeakPtr(), - gfx::Rect(view_->GetPhysicalBackingSize()))); + damage_rect)); // request->set_area(gfx::Rect(view_->GetPhysicalBackingSize())); @@ -842,13 +842,13 @@ void OffScreenWindow::OnSwapCompositorFrame( // Determine the damage rectangle for the current frame. This is the same // calculation that SwapDelegatedFrame uses. - // cc::RenderPass* root_pass = - // frame->delegated_frame_data->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)); - gfx::Rect damage_rect = gfx::Rect(GetVisibleViewportSize()); + cc::RenderPass* root_pass = + frame->delegated_frame_data->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)); + // gfx::Rect damage_rect = gfx::Rect(GetVisibleViewportSize()); if (frame->delegated_frame_data) delegated_frame_host_->SwapDelegatedFrame(output_surface_id, From 84a5c50b621c613d7e6ff3f07e3cd723ce39c65e Mon Sep 17 00:00:00 2001 From: gellert Date: Wed, 20 Jul 2016 11:30:06 +0200 Subject: [PATCH 5/8] breaks down osr api to separate files --- atom/browser/common_web_contents_delegate.cc | 2 +- atom/browser/osr_output_device.cc | 75 +++++++ atom/browser/osr_output_device.h | 54 +++++ atom/browser/osr_web_contents_view.cc | 167 ++++++++++++++ atom/browser/osr_web_contents_view.h | 70 ++++++ atom/browser/osr_window.cc | 219 ------------------- atom/browser/osr_window.h | 77 +------ filenames.gypi | 4 + 8 files changed, 373 insertions(+), 295 deletions(-) create mode 100644 atom/browser/osr_output_device.cc create mode 100644 atom/browser/osr_output_device.h create mode 100644 atom/browser/osr_web_contents_view.cc create mode 100644 atom/browser/osr_web_contents_view.h diff --git a/atom/browser/common_web_contents_delegate.cc b/atom/browser/common_web_contents_delegate.cc index 0b59d513d4..b89b7c9b19 100644 --- a/atom/browser/common_web_contents_delegate.cc +++ b/atom/browser/common_web_contents_delegate.cc @@ -34,7 +34,7 @@ #include "storage/browser/fileapi/isolated_context.h" #include "content/browser/web_contents/web_contents_impl.h" -#include "atom/browser/osr_window.h" +#include "atom/browser/osr_web_contents_view.h" #include "atom/browser/native_window_views.h" using content::BrowserThread; diff --git a/atom/browser/osr_output_device.cc b/atom/browser/osr_output_device.cc new file mode 100644 index 0000000000..d1c3201807 --- /dev/null +++ b/atom/browser/osr_output_device.cc @@ -0,0 +1,75 @@ +// Copyright (c) 2013 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/osr_output_device.h" + +#include + +namespace atom { + +OffScreenOutputDevice::OffScreenOutputDevice() { + std::cout << "OffScreenOutputDevice" << std::endl; +} + +OffScreenOutputDevice::~OffScreenOutputDevice() { + std::cout << "~OffScreenOutputDevice" << std::endl; +} + +void OffScreenOutputDevice::Resize( + const gfx::Size& pixel_size, float scale_factor) { + std::cout << "Resize" << std::endl; + std::cout << pixel_size.width() << "x" << pixel_size.height() << std::endl; + + scale_factor_ = scale_factor; + + if (viewport_pixel_size_ == pixel_size) return; + viewport_pixel_size_ = pixel_size; + + canvas_.reset(NULL); + bitmap_.reset(new SkBitmap); + bitmap_->allocN32Pixels(viewport_pixel_size_.width(), + viewport_pixel_size_.height(), + false); + if (bitmap_->drawsNothing()) { + std::cout << "drawsNothing" << std::endl; + NOTREACHED(); + bitmap_.reset(NULL); + return; + } + bitmap_->eraseARGB(0, 0, 0, 0); + + canvas_.reset(new SkCanvas(*bitmap_.get())); +} + +SkCanvas* OffScreenOutputDevice::BeginPaint(const gfx::Rect& damage_rect) { + std::cout << "BeginPaint" << std::endl; + DCHECK(canvas_.get()); + DCHECK(bitmap_.get()); + + damage_rect_ = damage_rect; + + return canvas_.get(); +} + +void OffScreenOutputDevice::EndPaint() { + std::cout << "EndPaint" << std::endl; + + DCHECK(canvas_.get()); + DCHECK(bitmap_.get()); + + if (!bitmap_.get()) return; + + cc::SoftwareOutputDevice::EndPaint(); + + SkAutoLockPixels bitmap_pixels_lock(*bitmap_.get()); + //saveSkBitmapToBMPFile(*(bitmap_.get()), "test.bmp"); + + uint8_t* pixels = reinterpret_cast(bitmap_->getPixels()); + for (int i = 0; i<16; i++) { + int x = static_cast(pixels[i]); + std::cout << std::hex << x << std::dec << std::endl; + } +} + +} // namespace atom diff --git a/atom/browser/osr_output_device.h b/atom/browser/osr_output_device.h new file mode 100644 index 0000000000..d8c56f60e9 --- /dev/null +++ b/atom/browser/osr_output_device.h @@ -0,0 +1,54 @@ +// Copyright (c) 2013 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_OSR_OUTPUT_DEVICE_H_ +#define ATOM_BROWSER_OSR_OUTPUT_DEVICE_H_ + +// #include "content/browser/renderer_host/render_widget_host_view_base.h" +// #include "content/browser/renderer_host/delegated_frame_host.h" +// #include "content/browser/renderer_host/resize_lock.h" +// #include "third_party/WebKit/public/platform/WebVector.h" +// #include "cc/scheduler/begin_frame_source.h" +// #include "content/browser/renderer_host/render_widget_host_impl.h" +// #include "cc/output/compositor_frame.h" +// #include "ui/gfx/geometry/point.h" +// #include "base/threading/thread.h" +// #include "ui/compositor/compositor.h" +// #include "ui/compositor/layer_delegate.h" +// #include "ui/compositor/layer_owner.h" +// #include "ui/base/ime/text_input_client.h" + +#include "cc/output/software_output_device.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "third_party/skia/include/core/SkCanvas.h" + +#include "content/browser/web_contents/web_contents_view.h" + +namespace atom { + +class OffScreenOutputDevice : public cc::SoftwareOutputDevice { +public: + OffScreenOutputDevice(); + ~OffScreenOutputDevice(); + + + // void saveSkBitmapToBMPFile(const SkBitmap& skBitmap, const char* path); + void Resize(const gfx::Size& pixel_size, float scale_factor) override; + + SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override; + + void EndPaint() override; + +private: + std::unique_ptr canvas_; + std::unique_ptr bitmap_; + gfx::Rect pending_damage_rect_; + + DISALLOW_COPY_AND_ASSIGN(OffScreenOutputDevice); +}; + + +} // namespace atom + +#endif // ATOM_BROWSER_OSR_OUTPUT_DEVICE_H_ diff --git a/atom/browser/osr_web_contents_view.cc b/atom/browser/osr_web_contents_view.cc new file mode 100644 index 0000000000..226340b0d2 --- /dev/null +++ b/atom/browser/osr_web_contents_view.cc @@ -0,0 +1,167 @@ +// Copyright (c) 2013 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/osr_web_contents_view.h" + +#include "atom/browser/osr_window.h" +#include + +namespace atom { + +OffScreenWebContentsView::OffScreenWebContentsView() { + std::cout << "OffScreenWebContentsView" << std::endl; + //std::this_thread::sleep_for(std::chrono::milliseconds(10000)); +} +OffScreenWebContentsView::~OffScreenWebContentsView() { + std::cout << "~OffScreenWebContentsView" << std::endl; +} + +// Returns the native widget that contains the contents of the tab. +gfx::NativeView OffScreenWebContentsView::GetNativeView() const{ + std::cout << "GetNativeView" << std::endl; + return gfx::NativeView(); +} + +// Returns the native widget with the main content of the tab (i.e. the main +// render view host, though there may be many popups in the tab as children of +// the container). +gfx::NativeView OffScreenWebContentsView::GetContentNativeView() const{ + std::cout << "GetContentNativeView" << std::endl; + return gfx::NativeView(); +} + +// Returns the outermost native view. This will be used as the parent for +// dialog boxes. +gfx::NativeWindow OffScreenWebContentsView::GetTopLevelNativeWindow() const{ + std::cout << "GetTopLevelNativeWindow" << std::endl; + return gfx::NativeWindow(); +} + +// Computes the rectangle for the native widget that contains the contents of +// the tab in the screen coordinate system. +void OffScreenWebContentsView::GetContainerBounds(gfx::Rect* out) const{ + std::cout << "GetContainerBounds" << std::endl; + *out = GetViewBounds(); +} + +// TODO(brettw) this is a hack. It's used in two places at the time of this +// writing: (1) when render view hosts switch, we need to size the replaced +// one to be correct, since it wouldn't have known about sizes that happened +// while it was hidden; (2) in constrained windows. +// +// (1) will be fixed once interstitials are cleaned up. (2) seems like it +// should be cleaned up or done some other way, since this works for normal +// WebContents without the special code. +void OffScreenWebContentsView::SizeContents(const gfx::Size& size){ + std::cout << "SizeContents" << std::endl; +} + +// Sets focus to the native widget for this tab. +void OffScreenWebContentsView::Focus(){ + std::cout << "OffScreenWebContentsView::Focus" << std::endl; +} + +// Sets focus to the appropriate element when the WebContents is shown the +// first time. +void OffScreenWebContentsView::SetInitialFocus(){ + std::cout << "SetInitialFocus" << std::endl; +} + +// Stores the currently focused view. +void OffScreenWebContentsView::StoreFocus(){ + std::cout << "StoreFocus" << std::endl; +} + +// Restores focus to the last focus view. If StoreFocus has not yet been +// invoked, SetInitialFocus is invoked. +void OffScreenWebContentsView::RestoreFocus(){ + std::cout << "RestoreFocus" << std::endl; +} + +// Returns the current drop data, if any. +content::DropData* OffScreenWebContentsView::GetDropData() const{ + std::cout << "GetDropData" << std::endl; + return nullptr; +} + +// Get the bounds of the View, relative to the parent. +gfx::Rect OffScreenWebContentsView::GetViewBounds() const{ + std::cout << "OffScreenWebContentsView::GetViewBounds" << std::endl; + return view_ ? view_->GetViewBounds() : gfx::Rect(); +} + +void OffScreenWebContentsView::CreateView( + const gfx::Size& initial_size, gfx::NativeView context){ + std::cout << "CreateView" << std::endl; + std::cout << initial_size.width() << "x" << initial_size.height() << std::endl; +} + +// Sets up the View that holds the rendered web page, receives messages for +// it and contains page plugins. The host view should be sized to the current +// size of the WebContents. +// +// |is_guest_view_hack| is temporary hack and will be removed once +// RenderWidgetHostViewGuest is not dependent on platform view. +// TODO(lazyboy): Remove |is_guest_view_hack| once http://crbug.com/330264 is +// fixed. +content::RenderWidgetHostViewBase* + OffScreenWebContentsView::CreateViewForWidget( + content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack){ + std::cout << "CreateViewForWidget" << std::endl; + view_ = new OffScreenWindow(render_widget_host); + return view_; +} + +// Creates a new View that holds a popup and receives messages for it. +content::RenderWidgetHostViewBase* + OffScreenWebContentsView::CreateViewForPopupWidget( + content::RenderWidgetHost* render_widget_host){ + std::cout << "CreateViewForPopupWidget" << std::endl; + view_ = new OffScreenWindow(render_widget_host); + return view_; +} + +// Sets the page title for the native widgets corresponding to the view. This +// is not strictly necessary and isn't expected to be displayed anywhere, but +// can aid certain debugging tools such as Spy++ on Windows where you are +// trying to find a specific window. +void OffScreenWebContentsView::SetPageTitle(const base::string16& title){ + std::cout << "SetPageTitle" << std::endl; + std::cout << title << std::endl; +} + +// Invoked when the WebContents is notified that the RenderView has been +// fully created. +void OffScreenWebContentsView::RenderViewCreated(content::RenderViewHost* host){ + std::cout << "RenderViewCreated" << std::endl; +} + +// Invoked when the WebContents is notified that the RenderView has been +// swapped in. +void OffScreenWebContentsView::RenderViewSwappedIn(content::RenderViewHost* host){ + std::cout << "RenderViewSwappedIn" << std::endl; +} + +// Invoked to enable/disable overscroll gesture navigation. +void OffScreenWebContentsView::SetOverscrollControllerEnabled(bool enabled){ + std::cout << "SetOverscrollControllerEnabled" << std::endl; +} + +#if defined(OS_MACOSX) +void OffScreenWebContentsView::SetAllowOtherViews(bool allow) { +} + +bool OffScreenWebContentsView::GetAllowOtherViews() const { + return false; +} + +bool OffScreenWebContentsView::IsEventTracking() const { + return false; +} + +void OffScreenWebContentsView::CloseTabAfterEventTracking() { +} +#endif // defined(OS_MACOSX) + +} // namespace atom diff --git a/atom/browser/osr_web_contents_view.h b/atom/browser/osr_web_contents_view.h new file mode 100644 index 0000000000..de73d5212c --- /dev/null +++ b/atom/browser/osr_web_contents_view.h @@ -0,0 +1,70 @@ +// Copyright (c) 2013 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_OSR_WEB_CONTENTS_VIEW_H_ +#define ATOM_BROWSER_OSR_WEB_CONTENTS_VIEW_H_ + +// #include "content/browser/renderer_host/render_widget_host_view_base.h" +// #include "content/browser/renderer_host/delegated_frame_host.h" +// #include "content/browser/renderer_host/resize_lock.h" +// #include "third_party/WebKit/public/platform/WebVector.h" +// #include "cc/scheduler/begin_frame_source.h" +// #include "content/browser/renderer_host/render_widget_host_impl.h" +// #include "cc/output/compositor_frame.h" +// #include "ui/gfx/geometry/point.h" +// #include "base/threading/thread.h" +// #include "ui/compositor/compositor.h" +// #include "ui/compositor/layer_delegate.h" +// #include "ui/compositor/layer_owner.h" +// #include "ui/base/ime/text_input_client.h" + +#include "content/browser/web_contents/web_contents_view.h" + +namespace atom { + +class OffScreenWebContentsView : public content::WebContentsView { +public: + OffScreenWebContentsView(); + ~OffScreenWebContentsView(); + + gfx::NativeView GetNativeView() const override; + gfx::NativeView GetContentNativeView() const override; + gfx::NativeWindow GetTopLevelNativeWindow() const override; + + void GetContainerBounds(gfx::Rect* out) const override; + void SizeContents(const gfx::Size& size) override; + void Focus() override; + void SetInitialFocus() override; + void StoreFocus() override; + void RestoreFocus() override; + content::DropData* GetDropData() const override; + gfx::Rect GetViewBounds() const override; + + void CreateView( + const gfx::Size& initial_size, gfx::NativeView context) override; + + content::RenderWidgetHostViewBase* CreateViewForWidget( + content::RenderWidgetHost* render_widget_host, + bool is_guest_view_hack) override; + content::RenderWidgetHostViewBase* CreateViewForPopupWidget( + content::RenderWidgetHost* render_widget_host) override; + + void SetPageTitle(const base::string16& title) override; + void RenderViewCreated(content::RenderViewHost* host) override; + void RenderViewSwappedIn(content::RenderViewHost* host) override; + void SetOverscrollControllerEnabled(bool enabled) override; + +#if defined(OS_MACOSX) + void SetAllowOtherViews(bool allow) override; + bool GetAllowOtherViews() const override; + bool IsEventTracking() const override; + void CloseTabAfterEventTracking() override; +#endif + +private: + content::RenderWidgetHostViewBase* view_; +}; +} // namespace atom + +#endif // ATOM_BROWSER_OSR_WEB_CONTENTS_VIEW_H_ diff --git a/atom/browser/osr_window.cc b/atom/browser/osr_window.cc index 050315dfc3..1efd0d9ce8 100644 --- a/atom/browser/osr_window.cc +++ b/atom/browser/osr_window.cc @@ -53,225 +53,6 @@ const int kFrameRetryLimit = 2; namespace atom { -OffScreenWebContentsView::OffScreenWebContentsView() { - std::cout << "OffScreenWebContentsView" << std::endl; - //std::this_thread::sleep_for(std::chrono::milliseconds(10000)); -} -OffScreenWebContentsView::~OffScreenWebContentsView() { - std::cout << "~OffScreenWebContentsView" << std::endl; -} - -// Returns the native widget that contains the contents of the tab. -gfx::NativeView OffScreenWebContentsView::GetNativeView() const{ - std::cout << "GetNativeView" << std::endl; - return gfx::NativeView(); -} - -// Returns the native widget with the main content of the tab (i.e. the main -// render view host, though there may be many popups in the tab as children of -// the container). -gfx::NativeView OffScreenWebContentsView::GetContentNativeView() const{ - std::cout << "GetContentNativeView" << std::endl; - return gfx::NativeView(); -} - -// Returns the outermost native view. This will be used as the parent for -// dialog boxes. -gfx::NativeWindow OffScreenWebContentsView::GetTopLevelNativeWindow() const{ - std::cout << "GetTopLevelNativeWindow" << std::endl; - return gfx::NativeWindow(); -} - -// Computes the rectangle for the native widget that contains the contents of -// the tab in the screen coordinate system. -void OffScreenWebContentsView::GetContainerBounds(gfx::Rect* out) const{ - std::cout << "GetContainerBounds" << std::endl; - *out = GetViewBounds(); -} - -// TODO(brettw) this is a hack. It's used in two places at the time of this -// writing: (1) when render view hosts switch, we need to size the replaced -// one to be correct, since it wouldn't have known about sizes that happened -// while it was hidden; (2) in constrained windows. -// -// (1) will be fixed once interstitials are cleaned up. (2) seems like it -// should be cleaned up or done some other way, since this works for normal -// WebContents without the special code. -void OffScreenWebContentsView::SizeContents(const gfx::Size& size){ - std::cout << "SizeContents" << std::endl; -} - -// Sets focus to the native widget for this tab. -void OffScreenWebContentsView::Focus(){ - std::cout << "OffScreenWebContentsView::Focus" << std::endl; -} - -// Sets focus to the appropriate element when the WebContents is shown the -// first time. -void OffScreenWebContentsView::SetInitialFocus(){ - std::cout << "SetInitialFocus" << std::endl; -} - -// Stores the currently focused view. -void OffScreenWebContentsView::StoreFocus(){ - std::cout << "StoreFocus" << std::endl; -} - -// Restores focus to the last focus view. If StoreFocus has not yet been -// invoked, SetInitialFocus is invoked. -void OffScreenWebContentsView::RestoreFocus(){ - std::cout << "RestoreFocus" << std::endl; -} - -// Returns the current drop data, if any. -content::DropData* OffScreenWebContentsView::GetDropData() const{ - std::cout << "GetDropData" << std::endl; - return nullptr; -} - -// Get the bounds of the View, relative to the parent. -gfx::Rect OffScreenWebContentsView::GetViewBounds() const{ - std::cout << "OffScreenWebContentsView::GetViewBounds" << std::endl; - return view_ ? view_->GetViewBounds() : gfx::Rect(); -} - -void OffScreenWebContentsView::CreateView( - const gfx::Size& initial_size, gfx::NativeView context){ - std::cout << "CreateView" << std::endl; - std::cout << initial_size.width() << "x" << initial_size.height() << std::endl; -} - -// Sets up the View that holds the rendered web page, receives messages for -// it and contains page plugins. The host view should be sized to the current -// size of the WebContents. -// -// |is_guest_view_hack| is temporary hack and will be removed once -// RenderWidgetHostViewGuest is not dependent on platform view. -// TODO(lazyboy): Remove |is_guest_view_hack| once http://crbug.com/330264 is -// fixed. -content::RenderWidgetHostViewBase* - OffScreenWebContentsView::CreateViewForWidget( - content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack){ - std::cout << "CreateViewForWidget" << std::endl; - view_ = new OffScreenWindow(render_widget_host); - return view_; -} - -// Creates a new View that holds a popup and receives messages for it. -content::RenderWidgetHostViewBase* - OffScreenWebContentsView::CreateViewForPopupWidget( - content::RenderWidgetHost* render_widget_host){ - std::cout << "CreateViewForPopupWidget" << std::endl; - view_ = new OffScreenWindow(render_widget_host); - return view_; -} - -// Sets the page title for the native widgets corresponding to the view. This -// is not strictly necessary and isn't expected to be displayed anywhere, but -// can aid certain debugging tools such as Spy++ on Windows where you are -// trying to find a specific window. -void OffScreenWebContentsView::SetPageTitle(const base::string16& title){ - std::cout << "SetPageTitle" << std::endl; - std::cout << title << std::endl; -} - -// Invoked when the WebContents is notified that the RenderView has been -// fully created. -void OffScreenWebContentsView::RenderViewCreated(content::RenderViewHost* host){ - std::cout << "RenderViewCreated" << std::endl; -} - -// Invoked when the WebContents is notified that the RenderView has been -// swapped in. -void OffScreenWebContentsView::RenderViewSwappedIn(content::RenderViewHost* host){ - std::cout << "RenderViewSwappedIn" << std::endl; -} - -// Invoked to enable/disable overscroll gesture navigation. -void OffScreenWebContentsView::SetOverscrollControllerEnabled(bool enabled){ - std::cout << "SetOverscrollControllerEnabled" << std::endl; -} - -#if defined(OS_MACOSX) -void OffScreenWebContentsView::SetAllowOtherViews(bool allow) { -} - -bool OffScreenWebContentsView::GetAllowOtherViews() const { - return false; -} - -bool OffScreenWebContentsView::IsEventTracking() const { - return false; -} - -void OffScreenWebContentsView::CloseTabAfterEventTracking() { -} -#endif // defined(OS_MACOSX) - -OffScreenOutputDevice::OffScreenOutputDevice() { - std::cout << "OffScreenOutputDevice" << std::endl; -} - -OffScreenOutputDevice::~OffScreenOutputDevice() { - std::cout << "~OffScreenOutputDevice" << std::endl; -} - -void OffScreenOutputDevice::Resize( - const gfx::Size& pixel_size, float scale_factor) { - std::cout << "Resize" << std::endl; - std::cout << pixel_size.width() << "x" << pixel_size.height() << std::endl; - - scale_factor_ = scale_factor; - - if (viewport_pixel_size_ == pixel_size) return; - viewport_pixel_size_ = pixel_size; - - canvas_.reset(NULL); - bitmap_.reset(new SkBitmap); - bitmap_->allocN32Pixels(viewport_pixel_size_.width(), - viewport_pixel_size_.height(), - false); - if (bitmap_->drawsNothing()) { - std::cout << "drawsNothing" << std::endl; - NOTREACHED(); - bitmap_.reset(NULL); - return; - } - bitmap_->eraseARGB(0, 0, 0, 0); - - canvas_.reset(new SkCanvas(*bitmap_.get())); -} - -SkCanvas* OffScreenOutputDevice::BeginPaint(const gfx::Rect& damage_rect) { - std::cout << "BeginPaint" << std::endl; - DCHECK(canvas_.get()); - DCHECK(bitmap_.get()); - - damage_rect_ = damage_rect; - - return canvas_.get(); -} - -void OffScreenOutputDevice::EndPaint() { - std::cout << "EndPaint" << std::endl; - - DCHECK(canvas_.get()); - DCHECK(bitmap_.get()); - - if (!bitmap_.get()) return; - - cc::SoftwareOutputDevice::EndPaint(); - - SkAutoLockPixels bitmap_pixels_lock(*bitmap_.get()); - //saveSkBitmapToBMPFile(*(bitmap_.get()), "test.bmp"); - - uint8_t* pixels = reinterpret_cast(bitmap_->getPixels()); - for (int i = 0; i<16; i++) { - int x = static_cast(pixels[i]); - std::cout << std::hex << x << std::dec << std::endl; - } -} - // Used for managing copy requests when GPU compositing is enabled. Based on // RendererOverridesHandler::InnerSwapCompositorFrame and // DelegatedFrameHost::CopyFromCompositingSurface. diff --git a/atom/browser/osr_window.h b/atom/browser/osr_window.h index d566cdda46..0418a62c2c 100644 --- a/atom/browser/osr_window.h +++ b/atom/browser/osr_window.h @@ -25,9 +25,6 @@ #include "cc/output/output_surface_client.h" #include "cc/scheduler/begin_frame_source.h" -#include "content/browser/web_contents/web_contents_view.h" -// #include "atom/browser/native_window_views.h" - #if defined(OS_WIN) #include #include "ui/gfx/win/window_impl.h" @@ -38,6 +35,8 @@ #include "ui/accelerated_widget_mac/accelerated_widget_mac.h" #endif +#include "atom/browser/osr_output_device.h" + #if defined(OS_MACOSX) #ifdef __OBJC__ @class CALayer; @@ -59,78 +58,6 @@ namespace atom { class CefCopyFrameGenerator; class CefBeginFrameTimer; -class OffScreenWebContentsView : public content::WebContentsView { -public: - OffScreenWebContentsView(); - ~OffScreenWebContentsView(); - - gfx::NativeView GetNativeView() const override; - gfx::NativeView GetContentNativeView() const override; - gfx::NativeWindow GetTopLevelNativeWindow() const override; - - void GetContainerBounds(gfx::Rect* out) const override; - void SizeContents(const gfx::Size& size) override; - void Focus() override; - void SetInitialFocus() override; - void StoreFocus() override; - void RestoreFocus() override; - content::DropData* GetDropData() const override; - gfx::Rect GetViewBounds() const override; - - void CreateView( - const gfx::Size& initial_size, gfx::NativeView context) override; - - content::RenderWidgetHostViewBase* CreateViewForWidget( - content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack) override; - content::RenderWidgetHostViewBase* CreateViewForPopupWidget( - content::RenderWidgetHost* render_widget_host) override; - - void SetPageTitle(const base::string16& title) override; - void RenderViewCreated(content::RenderViewHost* host) override; - void RenderViewSwappedIn(content::RenderViewHost* host) override; - void SetOverscrollControllerEnabled(bool enabled) override; - -#if defined(OS_MACOSX) - void SetAllowOtherViews(bool allow) override; - bool GetAllowOtherViews() const override; - bool IsEventTracking() const override; - void CloseTabAfterEventTracking() override; -#endif - -private: - content::RenderWidgetHostViewBase* view_; -}; - -class OffScreenOutputDevice : public cc::SoftwareOutputDevice { -public: - OffScreenOutputDevice(); - ~OffScreenOutputDevice(); - - - // void saveSkBitmapToBMPFile(const SkBitmap& skBitmap, const char* path); - void Resize(const gfx::Size& pixel_size, float scale_factor) override; - SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override; - void EndPaint() override; - -private: - std::unique_ptr canvas_; - std::unique_ptr bitmap_; - gfx::Rect pending_damage_rect_; - - DISALLOW_COPY_AND_ASSIGN(OffScreenOutputDevice); -}; - -class AtomCompositorDelegate : public ui::CompositorDelegate { -public: - AtomCompositorDelegate() {}; - ~AtomCompositorDelegate() {}; - - std::unique_ptr CreateSoftwareOutputDevice( - ui::Compositor* compositor) override { - return std::unique_ptr(new OffScreenOutputDevice); - } -}; - class OffScreenWindow : public content::RenderWidgetHostViewBase, #if defined(OS_MACOSX) diff --git a/filenames.gypi b/filenames.gypi index 325b766030..3678834ab1 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -204,6 +204,10 @@ 'atom/browser/native_window_mac.h', 'atom/browser/native_window_mac.mm', 'atom/browser/native_window_observer.h', + 'atom/browser/osr_web_contents_view.cc', + 'atom/browser/osr_web_contents_view.h', + 'atom/browser/osr_output_device.cc', + 'atom/browser/osr_output_device.h', 'atom/browser/osr_window.cc', 'atom/browser/osr_window.h', 'atom/browser/osr_window_win.cc', From 504c79cae73ac6f1da6fa268b6fc004a5b4e1753 Mon Sep 17 00:00:00 2001 From: gellert Date: Wed, 20 Jul 2016 11:32:59 +0200 Subject: [PATCH 6/8] removes commented includes --- atom/browser/osr_output_device.h | 16 ---------------- atom/browser/osr_web_contents_view.h | 15 +-------------- 2 files changed, 1 insertion(+), 30 deletions(-) diff --git a/atom/browser/osr_output_device.h b/atom/browser/osr_output_device.h index d8c56f60e9..0721f88e8e 100644 --- a/atom/browser/osr_output_device.h +++ b/atom/browser/osr_output_device.h @@ -5,20 +5,6 @@ #ifndef ATOM_BROWSER_OSR_OUTPUT_DEVICE_H_ #define ATOM_BROWSER_OSR_OUTPUT_DEVICE_H_ -// #include "content/browser/renderer_host/render_widget_host_view_base.h" -// #include "content/browser/renderer_host/delegated_frame_host.h" -// #include "content/browser/renderer_host/resize_lock.h" -// #include "third_party/WebKit/public/platform/WebVector.h" -// #include "cc/scheduler/begin_frame_source.h" -// #include "content/browser/renderer_host/render_widget_host_impl.h" -// #include "cc/output/compositor_frame.h" -// #include "ui/gfx/geometry/point.h" -// #include "base/threading/thread.h" -// #include "ui/compositor/compositor.h" -// #include "ui/compositor/layer_delegate.h" -// #include "ui/compositor/layer_owner.h" -// #include "ui/base/ime/text_input_client.h" - #include "cc/output/software_output_device.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkCanvas.h" @@ -32,7 +18,6 @@ public: OffScreenOutputDevice(); ~OffScreenOutputDevice(); - // void saveSkBitmapToBMPFile(const SkBitmap& skBitmap, const char* path); void Resize(const gfx::Size& pixel_size, float scale_factor) override; @@ -48,7 +33,6 @@ private: DISALLOW_COPY_AND_ASSIGN(OffScreenOutputDevice); }; - } // namespace atom #endif // ATOM_BROWSER_OSR_OUTPUT_DEVICE_H_ diff --git a/atom/browser/osr_web_contents_view.h b/atom/browser/osr_web_contents_view.h index de73d5212c..8b785eb720 100644 --- a/atom/browser/osr_web_contents_view.h +++ b/atom/browser/osr_web_contents_view.h @@ -5,20 +5,6 @@ #ifndef ATOM_BROWSER_OSR_WEB_CONTENTS_VIEW_H_ #define ATOM_BROWSER_OSR_WEB_CONTENTS_VIEW_H_ -// #include "content/browser/renderer_host/render_widget_host_view_base.h" -// #include "content/browser/renderer_host/delegated_frame_host.h" -// #include "content/browser/renderer_host/resize_lock.h" -// #include "third_party/WebKit/public/platform/WebVector.h" -// #include "cc/scheduler/begin_frame_source.h" -// #include "content/browser/renderer_host/render_widget_host_impl.h" -// #include "cc/output/compositor_frame.h" -// #include "ui/gfx/geometry/point.h" -// #include "base/threading/thread.h" -// #include "ui/compositor/compositor.h" -// #include "ui/compositor/layer_delegate.h" -// #include "ui/compositor/layer_owner.h" -// #include "ui/base/ime/text_input_client.h" - #include "content/browser/web_contents/web_contents_view.h" namespace atom { @@ -65,6 +51,7 @@ public: private: content::RenderWidgetHostViewBase* view_; }; + } // namespace atom #endif // ATOM_BROWSER_OSR_WEB_CONTENTS_VIEW_H_ From 81be0bc123390fe97a7bdcb885ab22f1864d6fef Mon Sep 17 00:00:00 2001 From: gellert Date: Fri, 22 Jul 2016 13:55:58 +0200 Subject: [PATCH 7/8] adds beginframe scheduling --- atom/browser/api/atom_api_web_contents.cc | 7 + atom/browser/common_web_contents_delegate.cc | 10 +- atom/browser/osr_web_contents_view.cc | 44 +-- atom/browser/osr_window.cc | 271 +++++++++++-------- atom/browser/osr_window.h | 6 + atom/browser/web_contents_preferences.cc | 8 + default_app/default_app.js | 238 +++++++++++++++- default_app/main.js | 2 +- 8 files changed, 434 insertions(+), 152 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 36b42ec78e..73dd9b3850 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -66,6 +66,9 @@ #include "third_party/WebKit/public/web/WebInputEvent.h" #include "third_party/WebKit/public/web/WebFindOptions.h" +#include "content/browser/web_contents/web_contents_impl.h" +#include "atom/browser/osr_web_contents_view.h" + #include "atom/common/node_includes.h" namespace { @@ -305,6 +308,10 @@ WebContents::WebContents(v8::Isolate* isolate, web_contents = content::WebContents::Create(params); } + content::WebContentsImpl* impl = + reinterpret_cast(web_contents); + impl->SetView(new OffScreenWebContentsView); + Observe(web_contents); InitWithWebContents(web_contents, session->browser_context()); diff --git a/atom/browser/common_web_contents_delegate.cc b/atom/browser/common_web_contents_delegate.cc index b89b7c9b19..f011e03cae 100644 --- a/atom/browser/common_web_contents_delegate.cc +++ b/atom/browser/common_web_contents_delegate.cc @@ -33,8 +33,8 @@ #include "content/public/browser/security_style_explanations.h" #include "storage/browser/fileapi/isolated_context.h" -#include "content/browser/web_contents/web_contents_impl.h" -#include "atom/browser/osr_web_contents_view.h" +// #include "content/browser/web_contents/web_contents_impl.h" +// #include "atom/browser/osr_web_contents_view.h" #include "atom/browser/native_window_views.h" using content::BrowserThread; @@ -188,15 +188,15 @@ void CommonWebContentsDelegate::InitWithWebContents( printing::PrintViewManagerBasic::CreateForWebContents(web_contents); printing::PrintPreviewMessageHandler::CreateForWebContents(web_contents); - content::WebContentsImpl* impl = - reinterpret_cast(web_contents); + // content::WebContentsImpl* impl = + // reinterpret_cast(web_contents); std::cout << "end" << std::endl; // Create InspectableWebContents. web_contents_.reset(brightray::InspectableWebContents::Create(web_contents)); web_contents_->SetDelegate(this); - impl->SetView(new OffScreenWebContentsView); + // impl->SetView(new OffScreenWebContentsView); std::cout << "end" << std::endl; } diff --git a/atom/browser/osr_web_contents_view.cc b/atom/browser/osr_web_contents_view.cc index 226340b0d2..90d425c7ca 100644 --- a/atom/browser/osr_web_contents_view.cc +++ b/atom/browser/osr_web_contents_view.cc @@ -10,16 +10,16 @@ namespace atom { OffScreenWebContentsView::OffScreenWebContentsView() { - std::cout << "OffScreenWebContentsView" << std::endl; + // std::cout << "OffScreenWebContentsView" << std::endl; //std::this_thread::sleep_for(std::chrono::milliseconds(10000)); } OffScreenWebContentsView::~OffScreenWebContentsView() { - std::cout << "~OffScreenWebContentsView" << std::endl; + // std::cout << "~OffScreenWebContentsView" << std::endl; } // Returns the native widget that contains the contents of the tab. gfx::NativeView OffScreenWebContentsView::GetNativeView() const{ - std::cout << "GetNativeView" << std::endl; + // std::cout << "GetNativeView" << std::endl; return gfx::NativeView(); } @@ -27,21 +27,21 @@ gfx::NativeView OffScreenWebContentsView::GetNativeView() const{ // render view host, though there may be many popups in the tab as children of // the container). gfx::NativeView OffScreenWebContentsView::GetContentNativeView() const{ - std::cout << "GetContentNativeView" << std::endl; + // std::cout << "GetContentNativeView" << std::endl; return gfx::NativeView(); } // Returns the outermost native view. This will be used as the parent for // dialog boxes. gfx::NativeWindow OffScreenWebContentsView::GetTopLevelNativeWindow() const{ - std::cout << "GetTopLevelNativeWindow" << std::endl; + // std::cout << "GetTopLevelNativeWindow" << std::endl; return gfx::NativeWindow(); } // Computes the rectangle for the native widget that contains the contents of // the tab in the screen coordinate system. void OffScreenWebContentsView::GetContainerBounds(gfx::Rect* out) const{ - std::cout << "GetContainerBounds" << std::endl; + // std::cout << "GetContainerBounds" << std::endl; *out = GetViewBounds(); } @@ -54,47 +54,47 @@ void OffScreenWebContentsView::GetContainerBounds(gfx::Rect* out) const{ // should be cleaned up or done some other way, since this works for normal // WebContents without the special code. void OffScreenWebContentsView::SizeContents(const gfx::Size& size){ - std::cout << "SizeContents" << std::endl; + // std::cout << "SizeContents" << std::endl; } // Sets focus to the native widget for this tab. void OffScreenWebContentsView::Focus(){ - std::cout << "OffScreenWebContentsView::Focus" << std::endl; + // std::cout << "OffScreenWebContentsView::Focus" << std::endl; } // Sets focus to the appropriate element when the WebContents is shown the // first time. void OffScreenWebContentsView::SetInitialFocus(){ - std::cout << "SetInitialFocus" << std::endl; + // std::cout << "SetInitialFocus" << std::endl; } // Stores the currently focused view. void OffScreenWebContentsView::StoreFocus(){ - std::cout << "StoreFocus" << std::endl; + // std::cout << "StoreFocus" << std::endl; } // Restores focus to the last focus view. If StoreFocus has not yet been // invoked, SetInitialFocus is invoked. void OffScreenWebContentsView::RestoreFocus(){ - std::cout << "RestoreFocus" << std::endl; + // std::cout << "RestoreFocus" << std::endl; } // Returns the current drop data, if any. content::DropData* OffScreenWebContentsView::GetDropData() const{ - std::cout << "GetDropData" << std::endl; + // std::cout << "GetDropData" << std::endl; return nullptr; } // Get the bounds of the View, relative to the parent. gfx::Rect OffScreenWebContentsView::GetViewBounds() const{ - std::cout << "OffScreenWebContentsView::GetViewBounds" << std::endl; + // std::cout << "OffScreenWebContentsView::GetViewBounds" << std::endl; return view_ ? view_->GetViewBounds() : gfx::Rect(); } void OffScreenWebContentsView::CreateView( const gfx::Size& initial_size, gfx::NativeView context){ - std::cout << "CreateView" << std::endl; - std::cout << initial_size.width() << "x" << initial_size.height() << std::endl; + // std::cout << "CreateView" << std::endl; + // std::cout << initial_size.width() << "x" << initial_size.height() << std::endl; } // Sets up the View that holds the rendered web page, receives messages for @@ -108,7 +108,7 @@ void OffScreenWebContentsView::CreateView( content::RenderWidgetHostViewBase* OffScreenWebContentsView::CreateViewForWidget( content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack){ - std::cout << "CreateViewForWidget" << std::endl; + // std::cout << "CreateViewForWidget" << std::endl; view_ = new OffScreenWindow(render_widget_host); return view_; } @@ -117,7 +117,7 @@ content::RenderWidgetHostViewBase* content::RenderWidgetHostViewBase* OffScreenWebContentsView::CreateViewForPopupWidget( content::RenderWidgetHost* render_widget_host){ - std::cout << "CreateViewForPopupWidget" << std::endl; + // std::cout << "CreateViewForPopupWidget" << std::endl; view_ = new OffScreenWindow(render_widget_host); return view_; } @@ -127,25 +127,25 @@ content::RenderWidgetHostViewBase* // can aid certain debugging tools such as Spy++ on Windows where you are // trying to find a specific window. void OffScreenWebContentsView::SetPageTitle(const base::string16& title){ - std::cout << "SetPageTitle" << std::endl; - std::cout << title << std::endl; + // std::cout << "SetPageTitle" << std::endl; + // std::cout << title << std::endl; } // Invoked when the WebContents is notified that the RenderView has been // fully created. void OffScreenWebContentsView::RenderViewCreated(content::RenderViewHost* host){ - std::cout << "RenderViewCreated" << std::endl; + // std::cout << "RenderViewCreated" << std::endl; } // Invoked when the WebContents is notified that the RenderView has been // swapped in. void OffScreenWebContentsView::RenderViewSwappedIn(content::RenderViewHost* host){ - std::cout << "RenderViewSwappedIn" << std::endl; + // std::cout << "RenderViewSwappedIn" << std::endl; } // Invoked to enable/disable overscroll gesture navigation. void OffScreenWebContentsView::SetOverscrollControllerEnabled(bool enabled){ - std::cout << "SetOverscrollControllerEnabled" << std::endl; + // std::cout << "SetOverscrollControllerEnabled" << std::endl; } #if defined(OS_MACOSX) diff --git a/atom/browser/osr_window.cc b/atom/browser/osr_window.cc index 1efd0d9ce8..1e62fb761c 100644 --- a/atom/browser/osr_window.cc +++ b/atom/browser/osr_window.cc @@ -128,7 +128,7 @@ class CefCopyFrameGenerator { weak_ptr_factory_.GetWeakPtr(), damage_rect)); - // request->set_area(gfx::Rect(view_->GetPhysicalBackingSize())); + request->set_area(gfx::Rect(view_->GetPhysicalBackingSize())); view_->DelegatedFrameHostGetLayer()->RequestCopyOfOutput( std::move(request)); @@ -137,7 +137,7 @@ class CefCopyFrameGenerator { void CopyFromCompositingSurfaceHasResult( const gfx::Rect& damage_rect, std::unique_ptr result) { - std::cout << "has result" << std::endl; + // std::cout << "has result" << std::endl; if (result->IsEmpty() || result->size().IsEmpty() || !view_->render_widget_host()) { OnCopyFrameCaptureFailure(damage_rect); @@ -292,17 +292,12 @@ class CefCopyFrameGenerator { const SkBitmap& bitmap, std::unique_ptr bitmap_pixels_lock) { - - // view_->OnPaint(damage_rect, bitmap.width(), bitmap.height(), - // bitmap.getPixels()); - uint8_t* pixels = reinterpret_cast(bitmap.getPixels()); - for (int i = 0; i<4; i++) { - int x = static_cast(pixels[i]); - std::cout << std::hex << x << std::dec << std::endl; - } + // for (int i = 0; i<4; i++) { + // int x = static_cast(pixels[i]); + // std::cout << std::hex << x << std::dec << std::endl; + // } if (view_->paintCallback) { - std::cout << "FRAME COPY ARRIVED" << std::endl; view_->paintCallback->Run(damage_rect, bitmap.width(), bitmap.height(), pixels); } @@ -386,6 +381,7 @@ class CefBeginFrameTimer : public cc::DelayBasedTimeSourceClient { OffScreenWindow::OffScreenWindow(content::RenderWidgetHost* host) : render_widget_host_(content::RenderWidgetHostImpl::From(host)), + software_output_device_(NULL), frame_rate_threshold_ms_(0), scale_factor_(1.0f), is_showing_(!render_widget_host_->is_hidden()), @@ -394,7 +390,7 @@ OffScreenWindow::OffScreenWindow(content::RenderWidgetHost* host) compositor_widget_(gfx::kNullAcceleratedWidget), weak_ptr_factory_(this) { DCHECK(render_widget_host_); - std::cout << "OffScreenWindow" << std::endl; + // std::cout << "OffScreenWindow" << std::endl; render_widget_host_->SetView(this); root_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR)); @@ -410,14 +406,29 @@ OffScreenWindow::OffScreenWindow(content::RenderWidgetHost* host) #endif // compositor_->SetDelegate(this); compositor_->SetRootLayer(root_layer_.get()); +} - frame_rate_threshold_ms_ = 1000 / 24; - begin_frame_timer_.reset(new CefBeginFrameTimer( - frame_rate_threshold_ms_, - base::Bind(&OffScreenWindow::OnBeginFrameTimerTick, - weak_ptr_factory_.GetWeakPtr()))); +void OffScreenWindow::ResizeRootLayer() { + SetFrameRate(); - // begin_frame_timer_->SetActive(true); + // const float orgScaleFactor = scale_factor_; + // SetDeviceScaleFactor(); + // const bool scaleFactorDidChange = (orgScaleFactor != scale_factor_); + // + // gfx::Size size; + // if (!IsPopupWidget()) + // size = GetViewBounds().size(); + // else + // size = popup_position_.size(); + // + // if (!scaleFactorDidChange && size == root_layer_->bounds().size()) + // return; + // + // const gfx::Size& size_in_pixels = + // gfx::ConvertSizeToPixel(scale_factor_, size); + // + // root_layer_->SetBounds(gfx::Rect(size)); + // compositor_->SetScaleAndSize(scale_factor_, size_in_pixels); } void OffScreenWindow::OnBeginFrameTimerTick() { @@ -425,9 +436,6 @@ void OffScreenWindow::OnBeginFrameTimerTick() { const base::TimeDelta vsync_period = base::TimeDelta::FromMilliseconds(frame_rate_threshold_ms_); SendBeginFrame(frame_time, vsync_period); - - std::cout << "tickkkk" << std::endl; - // copy_frame_generator_->GenerateCopyFrame(true, damage_rect); } void OffScreenWindow::SendBeginFrame(base::TimeTicks frame_time, @@ -445,6 +453,7 @@ void OffScreenWindow::SendBeginFrame(base::TimeTicks frame_time, render_widget_host_->GetRoutingID(), cc::BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, deadline, vsync_period, cc::BeginFrameArgs::NORMAL))); + // std::cout << "sent begin frame" << std::endl; } void OffScreenWindow::SetPaintCallback(const OnPaintCallback *callback) { @@ -452,7 +461,7 @@ void OffScreenWindow::SetPaintCallback(const OnPaintCallback *callback) { } OffScreenWindow::~OffScreenWindow() { - std::cout << "~OffScreenWindow" << std::endl; + // std::cout << "~OffScreenWindow" << std::endl; if (is_showing_) delegated_frame_host_->WasHidden(); @@ -464,7 +473,7 @@ OffScreenWindow::~OffScreenWindow() { } bool OffScreenWindow::OnMessageReceived(const IPC::Message& message) { - std::cout << "OnMessageReceived" << std::endl; + // std::cout << "OnMessageReceived" << std::endl; bool handled = true; IPC_BEGIN_MESSAGE_MAP(OffScreenWindow, message) @@ -479,19 +488,19 @@ bool OffScreenWindow::OnMessageReceived(const IPC::Message& message) { } void OffScreenWindow::InitAsChild(gfx::NativeView) { - std::cout << "InitAsChild" << std::endl; + // std::cout << "InitAsChild" << std::endl; } content::RenderWidgetHost* OffScreenWindow::GetRenderWidgetHost() const { - std::cout << "GetRenderWidgetHost" << std::endl; + // std::cout << "GetRenderWidgetHost" << std::endl; return render_widget_host_; } void OffScreenWindow::SetSize(const gfx::Size& size) { - std::cout << "SetSize" << std::endl; + // std::cout << "SetSize" << std::endl; size_ = size; - std::cout << size.width() << "x" << size.height() << std::endl; + // std::cout << size.width() << "x" << size.height() << std::endl; const gfx::Size& size_in_pixels = gfx::ConvertSizeToPixel(scale_factor_, size); @@ -501,50 +510,50 @@ void OffScreenWindow::SetSize(const gfx::Size& size) { } void OffScreenWindow::SetBounds(const gfx::Rect& new_bounds) { - std::cout << "SetBounds" << std::endl; + // std::cout << "SetBounds" << std::endl; } gfx::Vector2dF OffScreenWindow::GetLastScrollOffset() const { - std::cout << "GetLastScrollOffset" << std::endl; + // std::cout << "GetLastScrollOffset" << std::endl; return last_scroll_offset_; } gfx::NativeView OffScreenWindow::GetNativeView() const { - std::cout << "GetNativeView" << std::endl; + // std::cout << "GetNativeView" << std::endl; return gfx::NativeView(); } gfx::NativeViewId OffScreenWindow::GetNativeViewId() const { - std::cout << "GetNativeViewId" << std::endl; + // std::cout << "GetNativeViewId" << std::endl; return gfx::NativeViewId(); } gfx::NativeViewAccessible OffScreenWindow::GetNativeViewAccessible() { - std::cout << "GetNativeViewAccessible" << std::endl; + // std::cout << "GetNativeViewAccessible" << std::endl; return gfx::NativeViewAccessible(); } ui::TextInputClient* OffScreenWindow::GetTextInputClient() { - std::cout << "GetTextInputClient" << std::endl; + // std::cout << "GetTextInputClient" << std::endl; return nullptr; } void OffScreenWindow::Focus() { - std::cout << "Focus" << std::endl; + // std::cout << "Focus" << std::endl; } bool OffScreenWindow::HasFocus() const { - std::cout << "HasFocus" << std::endl; + // std::cout << "HasFocus" << std::endl; return false; } bool OffScreenWindow::IsSurfaceAvailableForCopy() const { - std::cout << "IsSurfaceAvailableForCopy" << std::endl; + // std::cout << "IsSurfaceAvailableForCopy" << std::endl; return delegated_frame_host_->CanCopyToBitmap(); } void OffScreenWindow::Show() { - std::cout << "Show" << std::endl; + // std::cout << "Show" << std::endl; if (is_showing_) return; @@ -556,7 +565,7 @@ void OffScreenWindow::Show() { } void OffScreenWindow::Hide() { - std::cout << "Hide" << std::endl; + // std::cout << "Hide" << std::endl; if (!is_showing_) return; @@ -568,54 +577,65 @@ void OffScreenWindow::Hide() { } bool OffScreenWindow::IsShowing() { - std::cout << "IsShowing" << std::endl; + // std::cout << "IsShowing" << std::endl; return is_showing_; } gfx::Rect OffScreenWindow::GetViewBounds() const { - std::cout << "GetViewBounds" << std::endl; - std::cout << size_.width() << "x" << size_.height() << std::endl; + // std::cout << "GetViewBounds" << std::endl; + // std::cout << size_.width() << "x" << size_.height() << std::endl; return gfx::Rect(size_); } gfx::Size OffScreenWindow::GetVisibleViewportSize() const { - std::cout << "GetVisibleViewportSize" << std::endl; - std::cout << size_.width() << "x" << size_.height() << std::endl; + // std::cout << "GetVisibleViewportSize" << std::endl; + // std::cout << size_.width() << "x" << size_.height() << std::endl; return size_; } void OffScreenWindow::SetInsets(const gfx::Insets& insets) { - std::cout << "SetInsets" << std::endl; + // std::cout << "SetInsets" << std::endl; } bool OffScreenWindow::LockMouse() { - std::cout << "LockMouse" << std::endl; + // std::cout << "LockMouse" << std::endl; return false; } void OffScreenWindow::UnlockMouse() { - std::cout << "UnlockMouse" << std::endl; + // std::cout << "UnlockMouse" << std::endl; } bool OffScreenWindow::GetScreenColorProfile(std::vector*) { - std::cout << "GetScreenColorProfile" << std::endl; + // std::cout << "GetScreenColorProfile" << std::endl; return false; } void OffScreenWindow::OnSwapCompositorFrame( uint32_t output_surface_id, std::unique_ptr frame) { - std::cout << "OnSwapCompositorFrame" << std::endl; + // std::cout << "OnSwapCompositorFrame" << std::endl; - std::cout << output_surface_id << std::endl; - - if (frame->delegated_frame_data) - std::cout << "delegated_frame_data" << std::endl; + // std::cout << output_surface_id << std::endl; if (frame->metadata.root_scroll_offset != last_scroll_offset_) { last_scroll_offset_ = frame->metadata.root_scroll_offset; } + if (!frame->delegated_frame_data) { + return; + } + + if (software_output_device_) { + // if (!begin_frame_timer_.get()) { + // software_output_device_->SetActive(true); + // } + + delegated_frame_host_->SwapDelegatedFrame(output_surface_id, + std::move(frame)); + return; + } + if (!copy_frame_generator_.get()) { copy_frame_generator_.reset( new CefCopyFrameGenerator(frame_rate_threshold_ms_, this)); @@ -629,7 +649,6 @@ void OffScreenWindow::OnSwapCompositorFrame( gfx::Rect damage_rect = gfx::ToEnclosingRect(gfx::RectF(root_pass->damage_rect)); damage_rect.Intersect(gfx::Rect(frame_size)); - // gfx::Rect damage_rect = gfx::Rect(GetVisibleViewportSize()); if (frame->delegated_frame_data) delegated_frame_host_->SwapDelegatedFrame(output_surface_id, @@ -637,78 +656,64 @@ void OffScreenWindow::OnSwapCompositorFrame( // Request a copy of the last compositor frame which will eventually call // OnPaint asynchronously. - std::cout << "FRAME COPY REQUESTED" << std::endl; + // std::cout << "FRAME COPY REQUESTED" << std::endl; copy_frame_generator_->GenerateCopyFrame(true, damage_rect); - - // gfx::Rect rect = gfx::Rect(GetVisibleViewportSize()); - // // The below code is similar in functionality to - // // DelegatedFrameHost::CopyFromCompositingSurface but we reuse the same - // // SkBitmap in the GPU codepath and avoid scaling where possible. - // std::unique_ptr request = - // cc::CopyOutputRequest::CreateRequest(base::Bind( - // &OffScreenWindow::CopyFromCompositingSurfaceHasResult, - // weak_ptr_factory_.GetWeakPtr(), - // rect)); - // - // request->set_area(gfx::Rect(GetPhysicalBackingSize())); - // DelegatedFrameHostGetLayer()->RequestCopyOfOutput( - // std::move(request)); } void OffScreenWindow::ClearCompositorFrame() { - std::cout << "ClearCompositorFrame" << std::endl; + // std::cout << "ClearCompositorFrame" << std::endl; delegated_frame_host_->ClearDelegatedFrame(); } void OffScreenWindow::InitAsPopup( content::RenderWidgetHostView *, const gfx::Rect &) { - std::cout << "InitAsPopup" << std::endl; + // std::cout << "InitAsPopup" << std::endl; } void OffScreenWindow::InitAsFullscreen(content::RenderWidgetHostView *) { - std::cout << "InitAsFullscreen" << std::endl; + // std::cout << "InitAsFullscreen" << std::endl; } void OffScreenWindow::UpdateCursor(const content::WebCursor &) { - std::cout << "UpdateCursor" << std::endl; + // std::cout << "UpdateCursor" << std::endl; } void OffScreenWindow::SetIsLoading(bool loading) { - std::cout << "SetIsLoading" << std::endl; + // std::cout << "SetIsLoading" << std::endl; } void OffScreenWindow::TextInputStateChanged( const ViewHostMsg_TextInputState_Params &) { - std::cout << "TextInputStateChanged" << std::endl; + // std::cout << "TextInputStateChanged" << std::endl; } void OffScreenWindow::ImeCancelComposition() { - std::cout << "ImeCancelComposition" << std::endl; + // std::cout << "ImeCancelComposition" << std::endl; } void OffScreenWindow::RenderProcessGone(base::TerminationStatus,int) { - std::cout << "RenderProcessGone" << std::endl; + // std::cout << "RenderProcessGone" << std::endl; Destroy(); } void OffScreenWindow::Destroy() { - std::cout << "Destroy" << std::endl; + // std::cout << "Destroy" << std::endl; } void OffScreenWindow::SetTooltipText(const base::string16 &) { - std::cout << "SetTooltipText" << std::endl; + // std::cout << "SetTooltipText" << std::endl; } void OffScreenWindow::SelectionBoundsChanged( const ViewHostMsg_SelectionBounds_Params &) { - std::cout << "SelectionBoundsChanged" << std::endl; + // std::cout << "SelectionBoundsChanged" << std::endl; } void OffScreenWindow::CopyFromCompositingSurface(const gfx::Rect& src_subrect, const gfx::Size& dst_size, const content::ReadbackRequestCallback& callback, const SkColorType preferred_color_type) { - std::cout << "CopyFromCompositingSurface" << std::endl; + // std::cout << "CopyFromCompositingSurface" << std::endl; delegated_frame_host_->CopyFromCompositingSurface( src_subrect, dst_size, callback, preferred_color_type); } @@ -717,35 +722,35 @@ void OffScreenWindow::CopyFromCompositingSurfaceToVideoFrame( const gfx::Rect& src_subrect, const scoped_refptr& target, const base::Callback& callback) { - std::cout << "CopyFromCompositingSurfaceToVideoFrame" << std::endl; + // std::cout << "CopyFromCompositingSurfaceToVideoFrame" << std::endl; delegated_frame_host_->CopyFromCompositingSurfaceToVideoFrame( src_subrect, target, callback); } bool OffScreenWindow::CanCopyToVideoFrame() const { - std::cout << "CanCopyToVideoFrame" << std::endl; + // std::cout << "CanCopyToVideoFrame" << std::endl; return delegated_frame_host_->CanCopyToVideoFrame(); } void OffScreenWindow::BeginFrameSubscription( std::unique_ptr subscriber) { - std::cout << "BeginFrameSubscription" << std::endl; + // std::cout << "BeginFrameSubscription" << std::endl; delegated_frame_host_->BeginFrameSubscription(std::move(subscriber)); } void OffScreenWindow::EndFrameSubscription() { - std::cout << "EndFrameSubscription" << std::endl; + // std::cout << "EndFrameSubscription" << std::endl; delegated_frame_host_->EndFrameSubscription(); } bool OffScreenWindow::HasAcceleratedSurface(const gfx::Size &) { - std::cout << "HasAcceleratedSurface" << std::endl; + // std::cout << "HasAcceleratedSurface" << std::endl; return false; } void OffScreenWindow::GetScreenInfo(blink::WebScreenInfo* results) { - std::cout << "GetScreenInfo" << std::endl; - std::cout << size_.width() << "x" << size_.height() << std::endl; + // std::cout << "GetScreenInfo" << std::endl; + // std::cout << size_.width() << "x" << size_.height() << std::endl; results->rect = gfx::Rect(size_); results->availableRect = gfx::Rect(size_); results->depth = 24; @@ -756,86 +761,86 @@ void OffScreenWindow::GetScreenInfo(blink::WebScreenInfo* results) { } bool OffScreenWindow::GetScreenColorProfile(blink::WebVector*) { - std::cout << "GetScreenColorProfile" << std::endl; + // std::cout << "GetScreenColorProfile" << std::endl; return false; } gfx::Rect OffScreenWindow::GetBoundsInRootWindow() { - std::cout << "GetBoundsInRootWindow" << std::endl; - std::cout << size_.width() << "x" << size_.height() << std::endl; + // std::cout << "GetBoundsInRootWindow" << std::endl; + // std::cout << size_.width() << "x" << size_.height() << std::endl; return gfx::Rect(size_); } void OffScreenWindow::LockCompositingSurface() { - std::cout << "LockCompositingSurface" << std::endl; + // std::cout << "LockCompositingSurface" << std::endl; } void OffScreenWindow::UnlockCompositingSurface() { - std::cout << "UnlockCompositingSurface" << std::endl; + // std::cout << "UnlockCompositingSurface" << std::endl; } void OffScreenWindow::ImeCompositionRangeChanged( const gfx::Range &, const std::vector&) { - std::cout << "ImeCompositionRangeChanged" << std::endl; + // std::cout << "ImeCompositionRangeChanged" << std::endl; } gfx::Size OffScreenWindow::GetPhysicalBackingSize() const { - std::cout << "GetPhysicalBackingSize" << std::endl; + // std::cout << "GetPhysicalBackingSize" << std::endl; return size_; } gfx::Size OffScreenWindow::GetRequestedRendererSize() const { - std::cout << "GetRequestedRendererSize" << std::endl; + // std::cout << "GetRequestedRendererSize" << std::endl; return size_; } int OffScreenWindow::DelegatedFrameHostGetGpuMemoryBufferClientId() const { - std::cout << "DelegatedFrameHostGetGpuMemoryBufferClientId" << std::endl; + // std::cout << "DelegatedFrameHostGetGpuMemoryBufferClientId" << std::endl; return render_widget_host_->GetProcess()->GetID(); } ui::Layer* OffScreenWindow::DelegatedFrameHostGetLayer() const { - std::cout << "DelegatedFrameHostGetLayer" << std::endl; + // std::cout << "DelegatedFrameHostGetLayer" << std::endl; return const_cast(root_layer_.get()); } bool OffScreenWindow::DelegatedFrameHostIsVisible() const { - std::cout << "DelegatedFrameHostIsVisible" << std::endl; - std::cout << !render_widget_host_->is_hidden() << std::endl; + // std::cout << "DelegatedFrameHostIsVisible" << std::endl; + // std::cout << !render_widget_host_->is_hidden() << std::endl; return !render_widget_host_->is_hidden(); } SkColor OffScreenWindow::DelegatedFrameHostGetGutterColor(SkColor color) const { - std::cout << "DelegatedFrameHostGetGutterColor" << std::endl; + // std::cout << "DelegatedFrameHostGetGutterColor" << std::endl; return color; } gfx::Size OffScreenWindow::DelegatedFrameHostDesiredSizeInDIP() const { - std::cout << "DelegatedFrameHostDesiredSizeInDIP" << std::endl; - std::cout << size_.width() << "x" << size_.height() << std::endl; + // std::cout << "DelegatedFrameHostDesiredSizeInDIP" << std::endl; + // std::cout << size_.width() << "x" << size_.height() << std::endl; return size_; } bool OffScreenWindow::DelegatedFrameCanCreateResizeLock() const { - std::cout << "DelegatedFrameCanCreateResizeLock" << std::endl; + // std::cout << "DelegatedFrameCanCreateResizeLock" << std::endl; return false; } std::unique_ptr OffScreenWindow::DelegatedFrameHostCreateResizeLock(bool) { - std::cout << "DelegatedFrameHostCreateResizeLock" << std::endl; + // std::cout << "DelegatedFrameHostCreateResizeLock" << std::endl; return nullptr; } void OffScreenWindow::DelegatedFrameHostResizeLockWasReleased() { - std::cout << "DelegatedFrameHostResizeLockWasReleased" << std::endl; + // std::cout << "DelegatedFrameHostResizeLockWasReleased" << std::endl; return render_widget_host_->WasResized(); } void OffScreenWindow::DelegatedFrameHostSendCompositorSwapAck( int output_surface_id, const cc::CompositorFrameAck& ack) { - std::cout << "DelegatedFrameHostSendCompositorSwapAck" << std::endl; - std::cout << output_surface_id << std::endl; + // std::cout << "DelegatedFrameHostSendCompositorSwapAck" << std::endl; + // std::cout << output_surface_id << std::endl; render_widget_host_->Send(new ViewMsg_SwapCompositorFrameAck( render_widget_host_->GetRoutingID(), output_surface_id, ack)); @@ -843,32 +848,68 @@ void OffScreenWindow::DelegatedFrameHostSendCompositorSwapAck( void OffScreenWindow::DelegatedFrameHostSendReclaimCompositorResources( int output_surface_id, const cc::CompositorFrameAck& ack) { - std::cout << "DelegatedFrameHostSendReclaimCompositorResources" << std::endl; - std::cout << output_surface_id << std::endl; + // std::cout << "DelegatedFrameHostSendReclaimCompositorResources" << std::endl; + // std::cout << output_surface_id << std::endl; render_widget_host_->Send(new ViewMsg_ReclaimCompositorResources( render_widget_host_->GetRoutingID(), output_surface_id, ack)); } void OffScreenWindow::DelegatedFrameHostOnLostCompositorResources() { - std::cout << "DelegatedFrameHostOnLostCompositorResources" << std::endl; + // std::cout << "DelegatedFrameHostOnLostCompositorResources" << std::endl; render_widget_host_->ScheduleComposite(); } void OffScreenWindow::DelegatedFrameHostUpdateVSyncParameters( const base::TimeTicks& timebase, const base::TimeDelta& interval) { - std::cout << "DelegatedFrameHostUpdateVSyncParameters" << std::endl; + // std::cout << "DelegatedFrameHostUpdateVSyncParameters" << std::endl; render_widget_host_->UpdateVSyncParameters(timebase, interval); } std::unique_ptr - OffScreenWindow::CreateSoftwareOutputDevice(ui::Compositor* compositor) { - std::cout << "CreateSoftwareOutputDevice" << std::endl; - return std::unique_ptr(new OffScreenOutputDevice); +OffScreenWindow::CreateSoftwareOutputDevice( + ui::Compositor* compositor) { + DCHECK_EQ(compositor_.get(), compositor); + DCHECK(!copy_frame_generator_); + DCHECK(!software_output_device_); + std::cout << "CREATED" << std::endl; + software_output_device_ = new OffScreenOutputDevice(); + return base::WrapUnique(software_output_device_); } void OffScreenWindow::OnSetNeedsBeginFrames(bool enabled) { - std::cout << "OnSetNeedsBeginFrames" << std::endl; + SetFrameRate(); + + begin_frame_timer_->SetActive(enabled); + + // std::cout << "OnSetNeedsBeginFrames" << enabled << std::endl; +} + +void OffScreenWindow::SetFrameRate() { + // Only set the frame rate one time. + if (frame_rate_threshold_ms_ != 0) + return; + + const int frame_rate = 120; + frame_rate_threshold_ms_ = 1000 / frame_rate; + + // Configure the VSync interval for the browser process. + compositor_->vsync_manager()->SetAuthoritativeVSyncInterval( + base::TimeDelta::FromMilliseconds(frame_rate_threshold_ms_)); + + if (copy_frame_generator_.get()) { + copy_frame_generator_->set_frame_rate_threshold_ms( + frame_rate_threshold_ms_); + } + + if (begin_frame_timer_.get()) { + begin_frame_timer_->SetFrameRateThresholdMs(frame_rate_threshold_ms_); + } else { + begin_frame_timer_.reset(new CefBeginFrameTimer( + frame_rate_threshold_ms_, + base::Bind(&OffScreenWindow::OnBeginFrameTimerTick, + weak_ptr_factory_.GetWeakPtr()))); + } } } // namespace atom diff --git a/atom/browser/osr_window.h b/atom/browser/osr_window.h index 0418a62c2c..74fdd64af7 100644 --- a/atom/browser/osr_window.h +++ b/atom/browser/osr_window.h @@ -190,12 +190,18 @@ public: std::unique_ptr paintCallback; void SetPaintCallback(const OnPaintCallback*); + private: + void SetFrameRate(); + void ResizeRootLayer(); + content::RenderWidgetHostImpl* render_widget_host_; std::unique_ptr copy_frame_generator_; std::unique_ptr begin_frame_timer_; + OffScreenOutputDevice* software_output_device_; + int frame_rate_threshold_ms_; float scale_factor_; diff --git a/atom/browser/web_contents_preferences.cc b/atom/browser/web_contents_preferences.cc index 8a7eee0920..1db71e6f01 100644 --- a/atom/browser/web_contents_preferences.cc +++ b/atom/browser/web_contents_preferences.cc @@ -19,11 +19,14 @@ #include "content/public/common/web_preferences.h" #include "native_mate/dictionary.h" #include "net/base/filename_util.h" +#include "cc/base/switches.h" #if defined(OS_WIN) #include "ui/gfx/switches.h" #endif +#include + DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::WebContentsPreferences); namespace atom { @@ -191,6 +194,11 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches( if (!visible) // Default state is visible. command_line->AppendSwitch("hidden-page"); } + + command_line->AppendSwitch(cc::switches::kEnableBeginFrameScheduling); + command_line->AppendSwitch(cc::switches::kShowFPSCounter); + // command_line->AppendSwitch("disable-gpu"); + // command_line->AppendSwitch("disable-gpu-compositing"); } // static diff --git a/default_app/default_app.js b/default_app/default_app.js index 7515d6cbf5..e0c7005d13 100644 --- a/default_app/default_app.js +++ b/default_app/default_app.js @@ -1,6 +1,14 @@ const {app, BrowserWindow} = require('electron') -var mainWindow = null +var mainWindow1 = null +var mainWindow2 = null +var mainWindow3 = null +var mainWindow4 = null +var mainWindow5 = null +var mainWindow6 = null +var mainWindow7 = null +var mainWindow8 = null + // Quit when all windows are closed. app.on('window-all-closed', () => { @@ -9,23 +17,235 @@ app.on('window-all-closed', () => { exports.load = (appUrl) => { app.on('ready', () => { - mainWindow = new BrowserWindow({ + mainWindow1 = new BrowserWindow({ width: 800, height: 600, autoHideMenuBar: true, backgroundColor: '#FFFFFF', - useContentSize: true + useContentSize: true, + webPreferences: { + nodeIntegration: false + } }) - mainWindow.loadURL(appUrl) - mainWindow.focus() - mainWindow.webContents.on('dom-ready', () => { - mainWindow.webContents.beginFrameSubscription(() => { + mainWindow1.loadURL(appUrl) + mainWindow1.focus() + mainWindow1.webContents.on('dom-ready', () => { + mainWindow1.webContents.beginFrameSubscription(() => { + console.log("asd") + }) + }) + var start1, end1 + start1 = +new Date(); + mainWindow1.webContents.on('paint', (e, rect, w, h, data) => { + end1 = +new Date(); + + const d = end1 - start1 + console.log(`browser #1: ${d < 10 ? ` ${d}` : d} ms`) + + start1 = end1 + }) + + mainWindow2 = new BrowserWindow({ + width: 800, + height: 600, + autoHideMenuBar: true, + backgroundColor: '#FFFFFF', + useContentSize: true, + webPreferences: { + nodeIntegration: false + } + }) + mainWindow2.loadURL(appUrl) + mainWindow2.focus() + mainWindow2.webContents.on('dom-ready', () => { + mainWindow2.webContents.beginFrameSubscription(() => { console.log("asd") }) }) - mainWindow.webContents.on('paint', (e, rect, w, h, data) => { - console.log('ELECTRON EVENT', rect, w, h, data) + var start2, end2 + start2 = +new Date(); + mainWindow2.webContents.on('paint', (e, rect, w, h, data) => { + end2 = +new Date(); + + const d = end2 - start2 + console.log(`browser #2: ${d < 10 ? ` ${d}` : d} ms`) + + start2 = end2 + }) + + mainWindow3 = new BrowserWindow({ + width: 800, + height: 600, + autoHideMenuBar: true, + backgroundColor: '#FFFFFF', + useContentSize: true, + webPreferences: { + nodeIntegration: false + } + }) + mainWindow3.loadURL(appUrl) + mainWindow3.focus() + mainWindow3.webContents.on('dom-ready', () => { + mainWindow3.webContents.beginFrameSubscription(() => { + console.log("asd") + }) + }) + + var start3, end3 + start3 = +new Date(); + mainWindow3.webContents.on('paint', (e, rect, w, h, data) => { + end3 = +new Date(); + + const d = end3 - start3 + console.log(`browser #3: ${d < 10 ? ` ${d}` : d} ms`) + + start3 = end3 + }) + + mainWindow4 = new BrowserWindow({ + width: 800, + height: 600, + autoHideMenuBar: true, + backgroundColor: '#FFFFFF', + useContentSize: true, + webPreferences: { + nodeIntegration: false + } + }) + mainWindow4.loadURL(appUrl) + mainWindow4.focus() + mainWindow4.webContents.on('dom-ready', () => { + mainWindow4.webContents.beginFrameSubscription(() => { + console.log("asd") + }) + }) + + var start4, end4 + start4 = +new Date(); + mainWindow4.webContents.on('paint', (e, rect, w, h, data) => { + end4 = +new Date(); + + const d = end4 - start4 + console.log(`browser #4: ${d < 10 ? ` ${d}` : d} ms`) + + start4 = end4 + }) + + mainWindow5 = new BrowserWindow({ + width: 800, + height: 600, + autoHideMenuBar: true, + backgroundColor: '#FFFFFF', + useContentSize: true, + webPreferences: { + nodeIntegration: false + } + }) + mainWindow5.loadURL(appUrl) + mainWindow5.focus() + mainWindow5.webContents.on('dom-ready', () => { + mainWindow5.webContents.beginFrameSubscription(() => { + console.log("asd") + }) + }) + + var start5, end5 + start5 = +new Date(); + mainWindow5.webContents.on('paint', (e, rect, w, h, data) => { + end5 = +new Date(); + + const d = end5 - start5 + console.log(`browser #5: ${d < 10 ? ` ${d}` : d} ms`) + + start5 = end5 + }) + + mainWindow6 = new BrowserWindow({ + width: 800, + height: 600, + autoHideMenuBar: true, + backgroundColor: '#FFFFFF', + useContentSize: true, + webPreferences: { + nodeIntegration: false + } + }) + mainWindow6.loadURL(appUrl) + mainWindow6.focus() + mainWindow6.webContents.on('dom-ready', () => { + mainWindow6.webContents.beginFrameSubscription(() => { + console.log("asd") + }) + }) + + var start6, end6 + start6 = +new Date(); + mainWindow6.webContents.on('paint', (e, rect, w, h, data) => { + end6 = +new Date(); + + const d = end6 - start6 + console.log(`browser #6: ${d < 10 ? ` ${d}` : d} ms`) + + start6 = end6 + }) + + mainWindow7 = new BrowserWindow({ + width: 800, + height: 600, + autoHideMenuBar: true, + backgroundColor: '#FFFFFF', + useContentSize: true, + webPreferences: { + nodeIntegration: false + } + }) + mainWindow7.loadURL(appUrl) + mainWindow7.focus() + mainWindow7.webContents.on('dom-ready', () => { + mainWindow7.webContents.beginFrameSubscription(() => { + console.log("asd") + }) + }) + + var start7, end7 + start7 = +new Date(); + mainWindow7.webContents.on('paint', (e, rect, w, h, data) => { + end7 = +new Date(); + + const d = end7 - start7 + console.log(`browser #7: ${d < 10 ? ` ${d}` : d} ms`) + + start7 = end7 + }) + + mainWindow8 = new BrowserWindow({ + width: 800, + height: 600, + autoHideMenuBar: true, + backgroundColor: '#FFFFFF', + useContentSize: true, + webPreferences: { + nodeIntegration: false + } + }) + mainWindow8.loadURL(appUrl) + mainWindow8.focus() + mainWindow8.webContents.on('dom-ready', () => { + mainWindow8.webContents.beginFrameSubscription(() => { + console.log("asd") + }) + }) + + var start8, end8 + start8 = +new Date(); + mainWindow8.webContents.on('paint', (e, rect, w, h, data) => { + end8 = +new Date(); + + const d = end8 - start8 + console.log(`browser #8: ${d < 10 ? ` ${d}` : d} ms`) + + start8 = end8 }) }) } diff --git a/default_app/main.js b/default_app/main.js index a5359972bb..b4ae85ed31 100644 --- a/default_app/main.js +++ b/default_app/main.js @@ -331,5 +331,5 @@ if (option.file && !option.webdriver) { startRepl() } else { const indexPath = path.join(__dirname, '/index.html') - loadApplicationByUrl(`https://vimeo.com/channels/staffpicks/174711575#t=7s`) + loadApplicationByUrl(`http://mrdoob.com/lab/javascript/requestanimationframe/`) } From 6eba509d5387b8dc122fbc61cc5821746d029eb1 Mon Sep 17 00:00:00 2001 From: gellert Date: Mon, 25 Jul 2016 15:55:00 +0200 Subject: [PATCH 8/8] removes logs and adds webcontentsview init --- atom/browser/api/atom_api_web_contents.cc | 8 +- atom/browser/osr_web_contents_view.cc | 13 + atom/browser/osr_web_contents_view.h | 13 +- atom/browser/osr_window.cc | 47 ++- atom/browser/osr_window.h | 3 + default_app/default_app.js | 404 +++++++++++----------- 6 files changed, 271 insertions(+), 217 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 73dd9b3850..6dd15fef35 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -305,13 +305,13 @@ WebContents::WebContents(v8::Isolate* isolate, web_contents = content::WebContents::Create(params); } else { content::WebContents::CreateParams params(session->browser_context()); + + params.view = new OffScreenWebContentsView(); + params.delegate_view = (content::RenderViewHostDelegateView *)params.view; + web_contents = content::WebContents::Create(params); } - content::WebContentsImpl* impl = - reinterpret_cast(web_contents); - impl->SetView(new OffScreenWebContentsView); - Observe(web_contents); InitWithWebContents(web_contents, session->browser_context()); diff --git a/atom/browser/osr_web_contents_view.cc b/atom/browser/osr_web_contents_view.cc index 90d425c7ca..a7cc4b652b 100644 --- a/atom/browser/osr_web_contents_view.cc +++ b/atom/browser/osr_web_contents_view.cc @@ -164,4 +164,17 @@ void OffScreenWebContentsView::CloseTabAfterEventTracking() { } #endif // defined(OS_MACOSX) +void OffScreenWebContentsView::StartDragging( + const content::DropData& drop_data, + blink::WebDragOperationsMask allowed_ops, + const gfx::ImageSkia& image, + const gfx::Vector2d& image_offset, + const content::DragEventSourceInfo& event_info) { +} + +void OffScreenWebContentsView::UpdateDragCursor( + blink::WebDragOperation operation) { +} + + } // namespace atom diff --git a/atom/browser/osr_web_contents_view.h b/atom/browser/osr_web_contents_view.h index 8b785eb720..543b9c4e28 100644 --- a/atom/browser/osr_web_contents_view.h +++ b/atom/browser/osr_web_contents_view.h @@ -5,11 +5,13 @@ #ifndef ATOM_BROWSER_OSR_WEB_CONTENTS_VIEW_H_ #define ATOM_BROWSER_OSR_WEB_CONTENTS_VIEW_H_ +#include "content/browser/renderer_host/render_view_host_delegate_view.h" #include "content/browser/web_contents/web_contents_view.h" namespace atom { -class OffScreenWebContentsView : public content::WebContentsView { +class OffScreenWebContentsView : public content::WebContentsView, + public content::RenderViewHostDelegateView { public: OffScreenWebContentsView(); ~OffScreenWebContentsView(); @@ -48,6 +50,15 @@ public: void CloseTabAfterEventTracking() override; #endif + // RenderViewHostDelegateView methods. + void StartDragging( + const content::DropData& drop_data, + blink::WebDragOperationsMask allowed_ops, + const gfx::ImageSkia& image, + const gfx::Vector2d& image_offset, + const content::DragEventSourceInfo& event_info) override; + void UpdateDragCursor(blink::WebDragOperation operation) override; + private: content::RenderWidgetHostViewBase* view_; }; diff --git a/atom/browser/osr_window.cc b/atom/browser/osr_window.cc index 1e62fb761c..8194913fb4 100644 --- a/atom/browser/osr_window.cc +++ b/atom/browser/osr_window.cc @@ -17,6 +17,7 @@ #include "ui/compositor/layer.h" #include "ui/compositor/layer_type.h" #include "base/location.h" +#include "base/time/time.h" #include "ui/gfx/native_widget_types.h" #include #include @@ -33,6 +34,8 @@ #include "content/public/browser/browser_thread.h" #include "cc/scheduler/delay_based_time_source.h" +#include "content/common/host_shared_bitmap_manager.h" + // const float kDefaultScaleFactor = 1.0; // The maximum number of retry counts if frame capture fails. @@ -66,6 +69,7 @@ class CefCopyFrameGenerator { frame_in_progress_(false), frame_retry_count_(0), weak_ptr_factory_(this) { + last_time_ = base::Time::Now(); } void GenerateCopyFrame( @@ -83,8 +87,10 @@ class CefCopyFrameGenerator { pending_damage_rect_.Union(damage_rect); // Don't attempt to generate a frame while one is currently in-progress. - if (frame_in_progress_) + if (frame_in_progress_) { + // std::cout << "FRAME IN PROGRESS" << std::endl; return; + } frame_in_progress_ = true; // Don't exceed the frame rate threshold. @@ -198,6 +204,14 @@ class CefCopyFrameGenerator { ignore_result(scoped_callback_runner.Release()); + // base::Time now = base::Time::Now(); + // std::cout << "delta: " << (now - last_time_).InMilliseconds() << " ms" << std::endl; + // last_time_ = now; + // frame_in_progress_ = false; + // if (view_->paintCallback) { + // view_->paintCallback->Run(damage_rect, bitmap_->width(), bitmap_->height(), + // pixels); + // } gl_helper->CropScaleReadbackAndCleanMailbox( texture_mailbox.mailbox(), texture_mailbox.sync_token(), @@ -293,6 +307,10 @@ class CefCopyFrameGenerator { std::unique_ptr bitmap_pixels_lock) { uint8_t* pixels = reinterpret_cast(bitmap.getPixels()); + + base::Time now = base::Time::Now(); + // std::cout << "delta: " << (now - last_time_).InMilliseconds() << " ms" << std::endl; + last_time_ = now; // for (int i = 0; i<4; i++) { // int x = static_cast(pixels[i]); // std::cout << std::hex << x << std::dec << std::endl; @@ -328,6 +346,8 @@ class CefCopyFrameGenerator { int frame_rate_threshold_ms_; OffScreenWindow* view_; + base::Time last_time_; + base::TimeTicks frame_start_time_; bool frame_pending_; bool frame_in_progress_; @@ -393,6 +413,8 @@ OffScreenWindow::OffScreenWindow(content::RenderWidgetHost* host) // std::cout << "OffScreenWindow" << std::endl; render_widget_host_->SetView(this); + last_time_ = base::Time::Now(); + root_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR)); CreatePlatformWidget(); @@ -406,6 +428,11 @@ OffScreenWindow::OffScreenWindow(content::RenderWidgetHost* host) #endif // compositor_->SetDelegate(this); compositor_->SetRootLayer(root_layer_.get()); + + ResizeRootLayer(); + + std::unique_ptr sbp = content::HostSharedBitmapManager::current()->AllocateSharedBitmap(gfx::Size(800, 600)); + printf("shared bitmap: %p\n", sbp.get()); } void OffScreenWindow::ResizeRootLayer() { @@ -614,7 +641,9 @@ bool OffScreenWindow::GetScreenColorProfile(std::vector*) { void OffScreenWindow::OnSwapCompositorFrame( uint32_t output_surface_id, std::unique_ptr frame) { - // std::cout << "OnSwapCompositorFrame" << std::endl; + base::Time now = base::Time::Now(); + // std::cout << "OnSwapCompositorFrame " << (now - last_time_).InMilliseconds() << " ms" << std::endl; + last_time_ = now; // std::cout << output_surface_id << std::endl; @@ -622,9 +651,8 @@ void OffScreenWindow::OnSwapCompositorFrame( last_scroll_offset_ = frame->metadata.root_scroll_offset; } - if (!frame->delegated_frame_data) { + if (!frame->delegated_frame_data) return; - } if (software_output_device_) { // if (!begin_frame_timer_.get()) { @@ -650,9 +678,8 @@ void OffScreenWindow::OnSwapCompositorFrame( gfx::ToEnclosingRect(gfx::RectF(root_pass->damage_rect)); damage_rect.Intersect(gfx::Rect(frame_size)); - if (frame->delegated_frame_data) - delegated_frame_host_->SwapDelegatedFrame(output_surface_id, - std::move(frame)); + delegated_frame_host_->SwapDelegatedFrame(output_surface_id, + std::move(frame)); // Request a copy of the last compositor frame which will eventually call // OnPaint asynchronously. @@ -887,10 +914,10 @@ void OffScreenWindow::OnSetNeedsBeginFrames(bool enabled) { void OffScreenWindow::SetFrameRate() { // Only set the frame rate one time. - if (frame_rate_threshold_ms_ != 0) - return; + // if (frame_rate_threshold_ms_ != 0) + // return; - const int frame_rate = 120; + const int frame_rate = 60; frame_rate_threshold_ms_ = 1000 / frame_rate; // Configure the VSync interval for the browser process. diff --git a/atom/browser/osr_window.h b/atom/browser/osr_window.h index 74fdd64af7..6e4bdf6def 100644 --- a/atom/browser/osr_window.h +++ b/atom/browser/osr_window.h @@ -14,6 +14,7 @@ #include "cc/output/compositor_frame.h" #include "ui/gfx/geometry/point.h" #include "base/threading/thread.h" +#include "base/time/time.h" #include "ui/compositor/compositor.h" #include "ui/compositor/layer_delegate.h" #include "ui/compositor/layer_owner.h" @@ -204,6 +205,8 @@ private: int frame_rate_threshold_ms_; + base::Time last_time_; + float scale_factor_; bool is_showing_; gfx::Vector2dF last_scroll_offset_; diff --git a/default_app/default_app.js b/default_app/default_app.js index e0c7005d13..ca9aced3fd 100644 --- a/default_app/default_app.js +++ b/default_app/default_app.js @@ -40,212 +40,212 @@ exports.load = (appUrl) => { end1 = +new Date(); const d = end1 - start1 - console.log(`browser #1: ${d < 10 ? ` ${d}` : d} ms`) + // console.log(`browser #1: ${d < 10 ? ` ${d}` : d} ms`) start1 = end1 }) - mainWindow2 = new BrowserWindow({ - width: 800, - height: 600, - autoHideMenuBar: true, - backgroundColor: '#FFFFFF', - useContentSize: true, - webPreferences: { - nodeIntegration: false - } - }) - mainWindow2.loadURL(appUrl) - mainWindow2.focus() - mainWindow2.webContents.on('dom-ready', () => { - mainWindow2.webContents.beginFrameSubscription(() => { - console.log("asd") - }) - }) + // mainWindow2 = new BrowserWindow({ + // width: 800, + // height: 600, + // autoHideMenuBar: true, + // backgroundColor: '#FFFFFF', + // useContentSize: true, + // webPreferences: { + // nodeIntegration: false + // } + // }) + // mainWindow2.loadURL(appUrl) + // mainWindow2.focus() + // mainWindow2.webContents.on('dom-ready', () => { + // mainWindow2.webContents.beginFrameSubscription(() => { + // console.log("asd") + // }) + // }) + // + // var start2, end2 + // start2 = +new Date(); + // mainWindow2.webContents.on('paint', (e, rect, w, h, data) => { + // end2 = +new Date(); + // + // const d = end2 - start2 + // console.log(`browser #2: ${d < 10 ? ` ${d}` : d} ms`) + // + // start2 = end2 + // }) + // + // mainWindow3 = new BrowserWindow({ + // width: 800, + // height: 600, + // autoHideMenuBar: true, + // backgroundColor: '#FFFFFF', + // useContentSize: true, + // webPreferences: { + // nodeIntegration: false + // } + // }) + // mainWindow3.loadURL(appUrl) + // mainWindow3.focus() + // mainWindow3.webContents.on('dom-ready', () => { + // mainWindow3.webContents.beginFrameSubscription(() => { + // console.log("asd") + // }) + // }) + // + // var start3, end3 + // start3 = +new Date(); + // mainWindow3.webContents.on('paint', (e, rect, w, h, data) => { + // end3 = +new Date(); + // + // const d = end3 - start3 + // console.log(`browser #3: ${d < 10 ? ` ${d}` : d} ms`) + // + // start3 = end3 + // }) + // + // mainWindow4 = new BrowserWindow({ + // width: 800, + // height: 600, + // autoHideMenuBar: true, + // backgroundColor: '#FFFFFF', + // useContentSize: true, + // webPreferences: { + // nodeIntegration: false + // } + // }) + // mainWindow4.loadURL(appUrl) + // mainWindow4.focus() + // mainWindow4.webContents.on('dom-ready', () => { + // mainWindow4.webContents.beginFrameSubscription(() => { + // console.log("asd") + // }) + // }) + // + // var start4, end4 + // start4 = +new Date(); + // mainWindow4.webContents.on('paint', (e, rect, w, h, data) => { + // end4 = +new Date(); + // + // const d = end4 - start4 + // console.log(`browser #4: ${d < 10 ? ` ${d}` : d} ms`) + // + // start4 = end4 + // }) - var start2, end2 - start2 = +new Date(); - mainWindow2.webContents.on('paint', (e, rect, w, h, data) => { - end2 = +new Date(); - - const d = end2 - start2 - console.log(`browser #2: ${d < 10 ? ` ${d}` : d} ms`) - - start2 = end2 - }) - - mainWindow3 = new BrowserWindow({ - width: 800, - height: 600, - autoHideMenuBar: true, - backgroundColor: '#FFFFFF', - useContentSize: true, - webPreferences: { - nodeIntegration: false - } - }) - mainWindow3.loadURL(appUrl) - mainWindow3.focus() - mainWindow3.webContents.on('dom-ready', () => { - mainWindow3.webContents.beginFrameSubscription(() => { - console.log("asd") - }) - }) - - var start3, end3 - start3 = +new Date(); - mainWindow3.webContents.on('paint', (e, rect, w, h, data) => { - end3 = +new Date(); - - const d = end3 - start3 - console.log(`browser #3: ${d < 10 ? ` ${d}` : d} ms`) - - start3 = end3 - }) - - mainWindow4 = new BrowserWindow({ - width: 800, - height: 600, - autoHideMenuBar: true, - backgroundColor: '#FFFFFF', - useContentSize: true, - webPreferences: { - nodeIntegration: false - } - }) - mainWindow4.loadURL(appUrl) - mainWindow4.focus() - mainWindow4.webContents.on('dom-ready', () => { - mainWindow4.webContents.beginFrameSubscription(() => { - console.log("asd") - }) - }) - - var start4, end4 - start4 = +new Date(); - mainWindow4.webContents.on('paint', (e, rect, w, h, data) => { - end4 = +new Date(); - - const d = end4 - start4 - console.log(`browser #4: ${d < 10 ? ` ${d}` : d} ms`) - - start4 = end4 - }) - - mainWindow5 = new BrowserWindow({ - width: 800, - height: 600, - autoHideMenuBar: true, - backgroundColor: '#FFFFFF', - useContentSize: true, - webPreferences: { - nodeIntegration: false - } - }) - mainWindow5.loadURL(appUrl) - mainWindow5.focus() - mainWindow5.webContents.on('dom-ready', () => { - mainWindow5.webContents.beginFrameSubscription(() => { - console.log("asd") - }) - }) - - var start5, end5 - start5 = +new Date(); - mainWindow5.webContents.on('paint', (e, rect, w, h, data) => { - end5 = +new Date(); - - const d = end5 - start5 - console.log(`browser #5: ${d < 10 ? ` ${d}` : d} ms`) - - start5 = end5 - }) - - mainWindow6 = new BrowserWindow({ - width: 800, - height: 600, - autoHideMenuBar: true, - backgroundColor: '#FFFFFF', - useContentSize: true, - webPreferences: { - nodeIntegration: false - } - }) - mainWindow6.loadURL(appUrl) - mainWindow6.focus() - mainWindow6.webContents.on('dom-ready', () => { - mainWindow6.webContents.beginFrameSubscription(() => { - console.log("asd") - }) - }) - - var start6, end6 - start6 = +new Date(); - mainWindow6.webContents.on('paint', (e, rect, w, h, data) => { - end6 = +new Date(); - - const d = end6 - start6 - console.log(`browser #6: ${d < 10 ? ` ${d}` : d} ms`) - - start6 = end6 - }) - - mainWindow7 = new BrowserWindow({ - width: 800, - height: 600, - autoHideMenuBar: true, - backgroundColor: '#FFFFFF', - useContentSize: true, - webPreferences: { - nodeIntegration: false - } - }) - mainWindow7.loadURL(appUrl) - mainWindow7.focus() - mainWindow7.webContents.on('dom-ready', () => { - mainWindow7.webContents.beginFrameSubscription(() => { - console.log("asd") - }) - }) - - var start7, end7 - start7 = +new Date(); - mainWindow7.webContents.on('paint', (e, rect, w, h, data) => { - end7 = +new Date(); - - const d = end7 - start7 - console.log(`browser #7: ${d < 10 ? ` ${d}` : d} ms`) - - start7 = end7 - }) - - mainWindow8 = new BrowserWindow({ - width: 800, - height: 600, - autoHideMenuBar: true, - backgroundColor: '#FFFFFF', - useContentSize: true, - webPreferences: { - nodeIntegration: false - } - }) - mainWindow8.loadURL(appUrl) - mainWindow8.focus() - mainWindow8.webContents.on('dom-ready', () => { - mainWindow8.webContents.beginFrameSubscription(() => { - console.log("asd") - }) - }) - - var start8, end8 - start8 = +new Date(); - mainWindow8.webContents.on('paint', (e, rect, w, h, data) => { - end8 = +new Date(); - - const d = end8 - start8 - console.log(`browser #8: ${d < 10 ? ` ${d}` : d} ms`) - - start8 = end8 - }) + // mainWindow5 = new BrowserWindow({ + // width: 800, + // height: 600, + // autoHideMenuBar: true, + // backgroundColor: '#FFFFFF', + // useContentSize: true, + // webPreferences: { + // nodeIntegration: false + // } + // }) + // mainWindow5.loadURL(appUrl) + // mainWindow5.focus() + // mainWindow5.webContents.on('dom-ready', () => { + // mainWindow5.webContents.beginFrameSubscription(() => { + // console.log("asd") + // }) + // }) + // + // var start5, end5 + // start5 = +new Date(); + // mainWindow5.webContents.on('paint', (e, rect, w, h, data) => { + // end5 = +new Date(); + // + // const d = end5 - start5 + // console.log(`browser #5: ${d < 10 ? ` ${d}` : d} ms`) + // + // start5 = end5 + // }) + // + // mainWindow6 = new BrowserWindow({ + // width: 800, + // height: 600, + // autoHideMenuBar: true, + // backgroundColor: '#FFFFFF', + // useContentSize: true, + // webPreferences: { + // nodeIntegration: false + // } + // }) + // mainWindow6.loadURL(appUrl) + // mainWindow6.focus() + // mainWindow6.webContents.on('dom-ready', () => { + // mainWindow6.webContents.beginFrameSubscription(() => { + // console.log("asd") + // }) + // }) + // + // var start6, end6 + // start6 = +new Date(); + // mainWindow6.webContents.on('paint', (e, rect, w, h, data) => { + // end6 = +new Date(); + // + // const d = end6 - start6 + // console.log(`browser #6: ${d < 10 ? ` ${d}` : d} ms`) + // + // start6 = end6 + // }) + // + // mainWindow7 = new BrowserWindow({ + // width: 800, + // height: 600, + // autoHideMenuBar: true, + // backgroundColor: '#FFFFFF', + // useContentSize: true, + // webPreferences: { + // nodeIntegration: false + // } + // }) + // mainWindow7.loadURL(appUrl) + // mainWindow7.focus() + // mainWindow7.webContents.on('dom-ready', () => { + // mainWindow7.webContents.beginFrameSubscription(() => { + // console.log("asd") + // }) + // }) + // + // var start7, end7 + // start7 = +new Date(); + // mainWindow7.webContents.on('paint', (e, rect, w, h, data) => { + // end7 = +new Date(); + // + // const d = end7 - start7 + // console.log(`browser #7: ${d < 10 ? ` ${d}` : d} ms`) + // + // start7 = end7 + // }) + // + // mainWindow8 = new BrowserWindow({ + // width: 800, + // height: 600, + // autoHideMenuBar: true, + // backgroundColor: '#FFFFFF', + // useContentSize: true, + // webPreferences: { + // nodeIntegration: false + // } + // }) + // mainWindow8.loadURL(appUrl) + // mainWindow8.focus() + // mainWindow8.webContents.on('dom-ready', () => { + // mainWindow8.webContents.beginFrameSubscription(() => { + // console.log("asd") + // }) + // }) + // + // var start8, end8 + // start8 = +new Date(); + // mainWindow8.webContents.on('paint', (e, rect, w, h, data) => { + // end8 = +new Date(); + // + // const d = end8 - start8 + // console.log(`browser #8: ${d < 10 ? ` ${d}` : d} ms`) + // + // start8 = end8 + // }) }) }