| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "gpu/ipc/service/child_window_surface_win.h" | 5 #include "gpu/ipc/service/child_window_surface_win.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| 11 #include "base/threading/thread.h" | 11 #include "base/threading/thread.h" |
| 12 #include "base/win/scoped_hdc.h" | 12 #include "base/win/scoped_hdc.h" |
| 13 #include "base/win/wrapped_window_proc.h" | 13 #include "base/win/wrapped_window_proc.h" |
| 14 #include "gpu/ipc/common/gpu_messages.h" | 14 #include "gpu/ipc/common/gpu_messages.h" |
| 15 #include "gpu/ipc/service/gpu_channel_manager.h" | 15 #include "gpu/ipc/service/gpu_channel_manager.h" |
| 16 #include "gpu/ipc/service/gpu_channel_manager_delegate.h" | 16 #include "gpu/ipc/service/gpu_channel_manager_delegate.h" |
| 17 #include "ui/base/win/hidden_window.h" | |
| 18 #include "ui/gfx/native_widget_types.h" | 17 #include "ui/gfx/native_widget_types.h" |
| 19 #include "ui/gfx/win/hwnd_util.h" | 18 #include "ui/gfx/win/hwnd_util.h" |
| 19 #include "ui/gfx/win/window_impl.h" |
| 20 #include "ui/gl/egl_util.h" | 20 #include "ui/gl/egl_util.h" |
| 21 #include "ui/gl/gl_context.h" | 21 #include "ui/gl/gl_context.h" |
| 22 #include "ui/gl/gl_surface_egl.h" | 22 #include "ui/gl/gl_surface_egl.h" |
| 23 #include "ui/gl/scoped_make_current.h" | 23 #include "ui/gl/scoped_make_current.h" |
| 24 | 24 |
| 25 namespace gpu { | 25 namespace gpu { |
| 26 | 26 |
| 27 // This owns the thread and contains data that's shared between the threads. | 27 // This owns the thread and contains data that's shared between the threads. |
| 28 struct SharedData { | 28 struct SharedData { |
| 29 SharedData() : thread("Window owner thread") {} | 29 SharedData() : thread("Window owner thread") {} |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 &base::win::WrappedWindowProc<IntermediateWindowProc>, CS_OWNDC, 0, 0, | 77 &base::win::WrappedWindowProc<IntermediateWindowProc>, CS_OWNDC, 0, 0, |
| 78 nullptr, reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)), nullptr, | 78 nullptr, reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)), nullptr, |
| 79 nullptr, nullptr, &intermediate_class); | 79 nullptr, nullptr, &intermediate_class); |
| 80 g_window_class = RegisterClassEx(&intermediate_class); | 80 g_window_class = RegisterClassEx(&intermediate_class); |
| 81 if (!g_window_class) { | 81 if (!g_window_class) { |
| 82 LOG(ERROR) << "RegisterClass failed."; | 82 LOG(ERROR) << "RegisterClass failed."; |
| 83 return; | 83 return; |
| 84 } | 84 } |
| 85 } | 85 } |
| 86 | 86 |
| 87 // Hidden popup window used as a parent for the child surface window. |
| 88 // Must be created and destroyed on the thread. |
| 89 class HiddenPopupWindow : public gfx::WindowImpl { |
| 90 public: |
| 91 static HWND Create() { |
| 92 gfx::WindowImpl* window = new HiddenPopupWindow; |
| 93 |
| 94 window->set_window_style(WS_POPUP); |
| 95 window->set_window_ex_style(WS_EX_TOOLWINDOW); |
| 96 window->Init(GetDesktopWindow(), gfx::Rect()); |
| 97 EnableWindow(window->hwnd(), FALSE); |
| 98 // The |window| instance is now owned by the window user data. |
| 99 DCHECK_EQ(window, gfx::GetWindowUserData(window->hwnd())); |
| 100 return window->hwnd(); |
| 101 } |
| 102 |
| 103 static void Destroy(HWND window) { |
| 104 // This uses the fact that the window user data contains a pointer |
| 105 // to gfx::WindowImpl instance. |
| 106 gfx::WindowImpl* window_data = |
| 107 reinterpret_cast<gfx::WindowImpl*>(gfx::GetWindowUserData(window)); |
| 108 DCHECK_EQ(window, window_data->hwnd()); |
| 109 DestroyWindow(window); |
| 110 delete window_data; |
| 111 } |
| 112 |
| 113 private: |
| 114 // Explicitly do nothing in Close. We do this as some external apps may get a |
| 115 // handle to this window and attempt to close it. |
| 116 void OnClose() {} |
| 117 |
| 118 CR_BEGIN_MSG_MAP_EX(HiddenPopupWindow) |
| 119 CR_MSG_WM_CLOSE(OnClose) |
| 120 CR_END_MSG_MAP() |
| 121 }; |
| 122 |
| 87 // This runs on the window owner thread. | 123 // This runs on the window owner thread. |
| 88 void CreateChildWindow(HWND hidden_window, | 124 void CreateWindowsOnThread(const gfx::Size& size, |
| 89 const gfx::Size& size, | 125 base::WaitableEvent* event, |
| 90 base::WaitableEvent* event, | 126 SharedData* shared_data, |
| 91 SharedData* shared_data, | 127 HWND* child_window, |
| 92 HWND* result) { | 128 HWND* parent_window) { |
| 93 InitializeWindowClass(); | 129 InitializeWindowClass(); |
| 94 DCHECK(g_window_class); | 130 DCHECK(g_window_class); |
| 95 | 131 |
| 132 // Create hidden parent window on the current thread. |
| 133 *parent_window = HiddenPopupWindow::Create(); |
| 134 // Create child window. |
| 96 HWND window = CreateWindowEx( | 135 HWND window = CreateWindowEx( |
| 97 WS_EX_NOPARENTNOTIFY, reinterpret_cast<wchar_t*>(g_window_class), L"", | 136 WS_EX_NOPARENTNOTIFY, reinterpret_cast<wchar_t*>(g_window_class), L"", |
| 98 WS_CHILDWINDOW | WS_DISABLED | WS_VISIBLE, 0, 0, size.width(), | 137 WS_CHILDWINDOW | WS_DISABLED | WS_VISIBLE, 0, 0, size.width(), |
| 99 size.height(), hidden_window, NULL, NULL, NULL); | 138 size.height(), *parent_window, NULL, NULL, NULL); |
| 100 CHECK(window); | 139 CHECK(window); |
| 101 *result = window; | 140 *child_window = window; |
| 102 gfx::SetWindowUserData(window, shared_data); | 141 gfx::SetWindowUserData(window, shared_data); |
| 103 event->Signal(); | 142 event->Signal(); |
| 104 } | 143 } |
| 105 | 144 |
| 106 // This runs on the main thread after the window was destroyed on window owner | 145 // This runs on the main thread after the window was destroyed on window owner |
| 107 // thread. | 146 // thread. |
| 108 void DestroySharedData(std::unique_ptr<SharedData> shared_data) { | 147 void DestroySharedData(std::unique_ptr<SharedData> shared_data) { |
| 109 shared_data->thread.Stop(); | 148 shared_data->thread.Stop(); |
| 110 } | 149 } |
| 111 | 150 |
| 112 // This runs on the window owner thread. | 151 // This runs on the window owner thread. |
| 113 void DestroyWindowOnThread(HWND window) { | 152 void DestroyWindowsOnThread(HWND child_window, HWND hidden_popup_window) { |
| 114 DestroyWindow(window); | 153 DestroyWindow(child_window); |
| 154 HiddenPopupWindow::Destroy(hidden_popup_window); |
| 115 } | 155 } |
| 116 | 156 |
| 117 } // namespace | 157 } // namespace |
| 118 | 158 |
| 119 ChildWindowSurfaceWin::ChildWindowSurfaceWin(GpuChannelManager* manager, | 159 ChildWindowSurfaceWin::ChildWindowSurfaceWin(GpuChannelManager* manager, |
| 120 HWND parent_window) | 160 HWND parent_window) |
| 121 : gl::NativeViewGLSurfaceEGL(0), | 161 : gl::NativeViewGLSurfaceEGL(0), |
| 122 parent_window_(parent_window), | 162 parent_window_(parent_window), |
| 123 manager_(manager), | 163 manager_(manager), |
| 124 alpha_(true), | 164 alpha_(true), |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 base::Thread::Options options(base::MessageLoop::TYPE_UI, 0); | 207 base::Thread::Options options(base::MessageLoop::TYPE_UI, 0); |
| 168 shared_data_->thread.StartWithOptions(options); | 208 shared_data_->thread.StartWithOptions(options); |
| 169 | 209 |
| 170 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, | 210 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 171 base::WaitableEvent::InitialState::NOT_SIGNALED); | 211 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 172 | 212 |
| 173 RECT window_rect; | 213 RECT window_rect; |
| 174 GetClientRect(parent_window_, &window_rect); | 214 GetClientRect(parent_window_, &window_rect); |
| 175 | 215 |
| 176 shared_data_->thread.task_runner()->PostTask( | 216 shared_data_->thread.task_runner()->PostTask( |
| 177 FROM_HERE, base::Bind(&CreateChildWindow, ui::GetHiddenWindow(), | 217 FROM_HERE, |
| 178 gfx::Rect(window_rect).size(), &event, | 218 base::Bind(&CreateWindowsOnThread, gfx::Rect(window_rect).size(), &event, |
| 179 shared_data_.get(), &window_)); | 219 shared_data_.get(), &window_, &initial_parent_window_)); |
| 180 event.Wait(); | 220 event.Wait(); |
| 181 | 221 |
| 182 manager_->delegate()->SendAcceleratedSurfaceCreatedChildWindow(parent_window_, | 222 manager_->delegate()->SendAcceleratedSurfaceCreatedChildWindow(parent_window_, |
| 183 window_); | 223 window_); |
| 184 return true; | 224 return true; |
| 185 } | 225 } |
| 186 | 226 |
| 187 bool ChildWindowSurfaceWin::Resize(const gfx::Size& size, | 227 bool ChildWindowSurfaceWin::Resize(const gfx::Size& size, |
| 188 float scale_factor, | 228 float scale_factor, |
| 189 bool has_alpha) { | 229 bool has_alpha) { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 FillRect(dc, &rect, reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH))); | 307 FillRect(dc, &rect, reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH))); |
| 268 shared_data_->rect_to_clear = gfx::Rect(); | 308 shared_data_->rect_to_clear = gfx::Rect(); |
| 269 } | 309 } |
| 270 } | 310 } |
| 271 | 311 |
| 272 ChildWindowSurfaceWin::~ChildWindowSurfaceWin() { | 312 ChildWindowSurfaceWin::~ChildWindowSurfaceWin() { |
| 273 if (shared_data_) { | 313 if (shared_data_) { |
| 274 scoped_refptr<base::TaskRunner> task_runner = | 314 scoped_refptr<base::TaskRunner> task_runner = |
| 275 shared_data_->thread.task_runner(); | 315 shared_data_->thread.task_runner(); |
| 276 task_runner->PostTaskAndReply( | 316 task_runner->PostTaskAndReply( |
| 277 FROM_HERE, base::Bind(&DestroyWindowOnThread, window_), | 317 FROM_HERE, |
| 318 base::Bind(&DestroyWindowsOnThread, window_, initial_parent_window_), |
| 278 base::Bind(&DestroySharedData, base::Passed(std::move(shared_data_)))); | 319 base::Bind(&DestroySharedData, base::Passed(std::move(shared_data_)))); |
| 279 } | 320 } |
| 280 } | 321 } |
| 281 | 322 |
| 282 } // namespace gpu | 323 } // namespace gpu |
| OLD | NEW |