diff options
author | scottmg@google.com <scottmg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-01 21:25:12 +0000 |
---|---|---|
committer | scottmg@google.com <scottmg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-01 21:25:12 +0000 |
commit | 56deedeafb9d4880280e33a4d35e769a4c119cf2 (patch) | |
tree | 54fc3c6b34e33dc4ade1c11c3355d39e52b1563c /win8/metro_driver | |
parent | 9d68072cff1c7d2e94ea2d35026f5cdd0736a3de (diff) | |
download | chromium_src-56deedeafb9d4880280e33a4d35e769a4c119cf2.zip chromium_src-56deedeafb9d4880280e33a4d35e769a4c119cf2.tar.gz chromium_src-56deedeafb9d4880280e33a4d35e769a4c119cf2.tar.bz2 |
Listen in the browser for a connection from a metro viewer process.
Render to the surface it provides to us.
BUG=151718
Review URL: https://codereview.chromium.org/10984007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@159559 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'win8/metro_driver')
-rw-r--r-- | win8/metro_driver/chrome_app_view.cc | 55 | ||||
-rw-r--r-- | win8/metro_driver/chrome_app_view.h | 3 | ||||
-rw-r--r-- | win8/metro_driver/direct3d_helper.cc | 128 | ||||
-rw-r--r-- | win8/metro_driver/direct3d_helper.h | 44 | ||||
-rw-r--r-- | win8/metro_driver/metro_driver.gyp | 8 |
5 files changed, 234 insertions, 4 deletions
diff --git a/win8/metro_driver/chrome_app_view.cc b/win8/metro_driver/chrome_app_view.cc index abac4b5..71392d0 100644 --- a/win8/metro_driver/chrome_app_view.cc +++ b/win8/metro_driver/chrome_app_view.cc @@ -4,6 +4,7 @@ #include "win8/metro_driver/stdafx.h" #include "win8/metro_driver/chrome_app_view.h" +#include "win8/metro_driver/direct3d_helper.h" #include <algorithm> #include <windows.applicationModel.datatransfer.h> @@ -13,11 +14,19 @@ #include "base/message_loop.h" #include "base/win/metro.h" +#include "base/threading/thread.h" +#include "ipc/ipc_channel.h" +#include "ipc/ipc_channel_proxy.h" +#include "ipc/ipc_sender.h" +#include "ui/gfx/native_widget_types.h" +#include "ui/metro_viewer/metro_viewer_messages.h" + // This include allows to send WM_SYSCOMMANDs to chrome. #include "chrome/app/chrome_command_ids.h" #include "win8/metro_driver/winrt_utils.h" #include "ui/base/ui_base_switches.h" + typedef winfoundtn::ITypedEventHandler< winapp::Core::CoreApplicationView*, winapp::Activation::IActivatedEventArgs*> ActivatedHandler; @@ -282,6 +291,26 @@ void FlipFrameWindowsInternal() { } } +class ChromeChannelListener : public IPC::Listener { + public: + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { + DVLOG(1) << "Received ipc message " << message.type(); + return true; + } + + virtual void OnChannelError() OVERRIDE { + DVLOG(1) << "Channel error"; + MessageLoop::current()->Quit(); + } + + void Init(IPC::Sender* s) { + sender_ = s; + } + + private: + IPC::Sender* sender_; +}; + } // namespace HRESULT ChromeAppView::TileRequestCreateDone( @@ -715,6 +744,10 @@ ChromeAppView::SetWindow(winui::Core::ICoreWindow* window) { DVLOG(1) << "Created appview instance."; + direct3d_helper_.Initialize(window); + + DVLOG(1) << "Initialized Direct3D."; + hr = devices_handler_.Initialize(window); // Don't check or return the failure here, we need to let the app // initialization succeed. Even if we won't be able to access devices @@ -786,7 +819,7 @@ void ChromeAppView::CheckForOSKActivation() { IFACEMETHODIMP ChromeAppView::Run() { - DVLOG(1) << __FUNCTION__ << ", hwnd=" << LONG_PTR(window_.Get()); + DVLOG(1) << __FUNCTION__; mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher; HRESULT hr = window_->get_Dispatcher(&dispatcher); CheckHR(hr, "Dispatcher failed."); @@ -804,6 +837,21 @@ ChromeAppView::Run() { // Announce our message loop to the world. globals.appview_msg_loop = msg_loop.message_loop_proxy(); + // The thread needs to out-live the ChannelProxy. + base::Thread thread("metro_IO_thread"); + base::Thread::Options options; + options.message_loop_type = MessageLoop::TYPE_IO; + thread.StartWithOptions(options); + + ChromeChannelListener channel_listener; + IPC::ChannelProxy chan("viewer", IPC::Channel::MODE_NAMED_CLIENT, + &channel_listener, thread.message_loop_proxy()); + channel_listener.Init(&chan); + chan.Send(new MetroViewerHostMsg_SetTargetSurface( + gfx::NativeViewId(globals.core_window))); + + DVLOG(1) << "ICoreWindow sent " << globals.core_window; + // And post the task that'll do the inner Metro message pumping to it. msg_loop.PostTask(FROM_HERE, base::Bind(&RunMessageLoop, dispatcher.Get())); @@ -912,17 +960,20 @@ HRESULT ChromeAppView::OnActivate(winapp::Core::ICoreApplicationView*, DVLOG(1) << "CoreWindow found: " << std::hex << globals.core_window; + +#if !defined(USE_AURA) if (!globals.host_thread) { DWORD chrome_ui_thread_id = 0; globals.host_thread = ::CreateThread(NULL, 0, HostMainThreadProc, NULL, 0, - &chrome_ui_thread_id); + &chrome_ui_thread_id); if (!globals.host_thread) { NOTREACHED() << "thread creation failed."; return E_UNEXPECTED; } } +#endif if (RegisterHotKey(globals.core_window, kFlipWindowsHotKeyId, MOD_CONTROL, VK_F12)) { diff --git a/win8/metro_driver/chrome_app_view.h b/win8/metro_driver/chrome_app_view.h index 80f309d..cca7864 100644 --- a/win8/metro_driver/chrome_app_view.h +++ b/win8/metro_driver/chrome_app_view.h @@ -20,6 +20,7 @@ #include "base/synchronization/lock.h" #include "win8/metro_driver/chrome_url_launch_handler.h" #include "win8/metro_driver/devices_handler.h" +#include "win8/metro_driver/direct3d_helper.h" #include "win8/metro_driver/metro_dialog_box.h" #include "win8/metro_driver/settings_handler.h" #include "win8/metro_driver/toast_notification_handler.h" @@ -132,6 +133,8 @@ class ChromeAppView int osk_offset_adjustment_; MetroDialogBox dialog_box_; + + metro_driver::Direct3DHelper direct3d_helper_; }; class ChromeAppViewFactory diff --git a/win8/metro_driver/direct3d_helper.cc b/win8/metro_driver/direct3d_helper.cc new file mode 100644 index 0000000..a4c3201 --- /dev/null +++ b/win8/metro_driver/direct3d_helper.cc @@ -0,0 +1,128 @@ +// Copyright 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "stdafx.h" +#include "win8/metro_driver/direct3d_helper.h" +#include "win8/metro_driver/winrt_utils.h" + +#include "base/logging.h" + +#include <windows.graphics.display.h> + +namespace { + +void CheckIfFailed(HRESULT hr) { + DCHECK(!FAILED(hr)); + if (FAILED(hr)) + DVLOG(ERROR) << "Direct3D call failed, hr = " << hr; +} + +float GetLogicalDpi() { + mswr::ComPtr<wingfx::Display::IDisplayPropertiesStatics> display_properties; + CheckIfFailed(winrt_utils::CreateActivationFactory( + RuntimeClass_Windows_Graphics_Display_DisplayProperties, + display_properties.GetAddressOf())); + float dpi = 0.0; + CheckIfFailed(display_properties->get_LogicalDpi(&dpi)); + return dpi; +} + +float ConvertDipsToPixels(float dips) { + static const float dips_per_inch = 96.f; + float logical_dpi = GetLogicalDpi(); + return floor(dips * logical_dpi / dips_per_inch + 0.5f); +} + +} + +namespace metro_driver { + +Direct3DHelper::Direct3DHelper() { +} + +Direct3DHelper::~Direct3DHelper() { +} + +void Direct3DHelper::Initialize(winui::Core::ICoreWindow* window) { + window_ = window; + CreateDeviceResources(); + CreateWindowSizeDependentResources(); +} + +// TODO(scottmg): Need to handle resize messages and recreation. + +void Direct3DHelper::CreateDeviceResources() { + unsigned int creation_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; + D3D_FEATURE_LEVEL feature_levels[] = { + D3D_FEATURE_LEVEL_11_1, + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, + D3D_FEATURE_LEVEL_9_3, + D3D_FEATURE_LEVEL_9_2, + D3D_FEATURE_LEVEL_9_1, + }; + + mswr::ComPtr<ID3D11Device> device; + mswr::ComPtr<ID3D11DeviceContext> context; + CheckIfFailed( + D3D11CreateDevice( + nullptr, + D3D_DRIVER_TYPE_HARDWARE, + nullptr, + creation_flags, + feature_levels, + ARRAYSIZE(feature_levels), + D3D11_SDK_VERSION, + &device, + &feature_level_, + &context)); + CheckIfFailed(device.As(&d3d_device_)); + CheckIfFailed(context.As(&d3d_context_)); +} + +void Direct3DHelper::CreateWindowSizeDependentResources() { + CheckIfFailed(window_->get_Bounds(&window_bounds_)); + float window_width = ConvertDipsToPixels(window_bounds_.Width); + float window_height = ConvertDipsToPixels(window_bounds_.Height); + + // TODO(scottmg): Orientation. + + if (swap_chain_ != nullptr) { + // TODO(scottmg): Resize if it already exists. + NOTIMPLEMENTED(); + } else { + DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = { 0 }; + swap_chain_desc.Width = window_width; + swap_chain_desc.Height = window_height; + swap_chain_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + swap_chain_desc.Stereo = false; + swap_chain_desc.SampleDesc.Count = 1; + swap_chain_desc.SampleDesc.Quality = 0; + swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swap_chain_desc.BufferCount = 2; // TODO(scottmg): Probably 1 is fine. + swap_chain_desc.Scaling = DXGI_SCALING_NONE; + swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + swap_chain_desc.Flags = 0; + + mswr::ComPtr<IDXGIDevice1> dxgi_device; + CheckIfFailed(d3d_device_.As(&dxgi_device)); + + mswr::ComPtr<IDXGIAdapter> dxgi_adapter; + CheckIfFailed(dxgi_device->GetAdapter(&dxgi_adapter)); + + mswr::ComPtr<IDXGIFactory2> dxgi_factory; + CheckIfFailed(dxgi_adapter->GetParent( + __uuidof(IDXGIFactory2), &dxgi_factory)); + + CheckIfFailed(dxgi_factory->CreateSwapChainForCoreWindow( + d3d_device_.Get(), + reinterpret_cast<IUnknown*>(window_), + &swap_chain_desc, + nullptr, + &swap_chain_)); + } +} + +} // namespace metro_driver diff --git a/win8/metro_driver/direct3d_helper.h b/win8/metro_driver/direct3d_helper.h new file mode 100644 index 0000000..a5547ba --- /dev/null +++ b/win8/metro_driver/direct3d_helper.h @@ -0,0 +1,44 @@ +// Copyright 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WIN8_METRO_DRIVER_DIRECT3D_HELPER_ +#define WIN8_METRO_DRIVER_DIRECT3D_HELPER_ + +#include "base/basictypes.h" + +#include <windows.ui.core.h> +#include <windows.foundation.h> +#include <d3d11_1.h> + +namespace metro_driver { + +// We need to initalize a Direct3D device and swapchain so that the browser +// can Present to our HWND. This class takes care of creating and keeping the +// swapchain up to date. +class Direct3DHelper { + public: + Direct3DHelper(); + ~Direct3DHelper(); + + void Initialize(winui::Core::ICoreWindow* window); + + private: + void CreateDeviceResources(); + void CreateWindowSizeDependentResources(); + + winui::Core::ICoreWindow* window_; + + mswr::ComPtr<ID3D11Device1> d3d_device_; + mswr::ComPtr<ID3D11DeviceContext1> d3d_context_; + mswr::ComPtr<IDXGISwapChain1> swap_chain_; + D3D_FEATURE_LEVEL feature_level_; + + ABI::Windows::Foundation::Rect window_bounds_; + + DISALLOW_COPY_AND_ASSIGN(Direct3DHelper); +}; + +} // namespace metro_driver + +#endif // WIN8_METRO_DRIVER_DIRECT3D_HELPER_ diff --git a/win8/metro_driver/metro_driver.gyp b/win8/metro_driver/metro_driver.gyp index 94960cdf..e8f6481 100644 --- a/win8/metro_driver/metro_driver.gyp +++ b/win8/metro_driver/metro_driver.gyp @@ -31,10 +31,12 @@ 'type': 'shared_library', 'dependencies': [ '../../base/base.gyp:base', - '../../build/temp_gyp/googleurl.gyp:googleurl', + '../../build/temp_gyp/googleurl.gyp:googleurl', '../../crypto/crypto.gyp:crypto', - '../../sandbox/sandbox.gyp:sandbox', '../../google_update/google_update.gyp:google_update', + '../../ipc/ipc.gyp:ipc', + '../../sandbox/sandbox.gyp:sandbox', + '../../ui/metro_viewer/metro_viewer.gyp:metro_viewer', '../win8.gyp:check_sdk_patch', ], 'sources': [ @@ -46,6 +48,8 @@ '../delegate_execute/chrome_util.h', 'devices_handler.cc', 'devices_handler.h', + 'direct3d_helper.cc', + 'direct3d_helper.h', 'file_picker.h', 'file_picker.cc', 'metro_dialog_box.cc', |