summaryrefslogtreecommitdiffstats
path: root/win8/metro_driver
diff options
context:
space:
mode:
authorscottmg@google.com <scottmg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-01 21:25:12 +0000
committerscottmg@google.com <scottmg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-01 21:25:12 +0000
commit56deedeafb9d4880280e33a4d35e769a4c119cf2 (patch)
tree54fc3c6b34e33dc4ade1c11c3355d39e52b1563c /win8/metro_driver
parent9d68072cff1c7d2e94ea2d35026f5cdd0736a3de (diff)
downloadchromium_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.cc55
-rw-r--r--win8/metro_driver/chrome_app_view.h3
-rw-r--r--win8/metro_driver/direct3d_helper.cc128
-rw-r--r--win8/metro_driver/direct3d_helper.h44
-rw-r--r--win8/metro_driver/metro_driver.gyp8
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',