Chromium Code Reviews| Index: gpu/ipc/service/child_window_surface_win.cc |
| diff --git a/gpu/ipc/service/child_window_surface_win.cc b/gpu/ipc/service/child_window_surface_win.cc |
| index 762fbd117391233704e07375d64474912e305e1c..f9013e8f8e5038092557f30e3686c8cb4aba011a 100644 |
| --- a/gpu/ipc/service/child_window_surface_win.cc |
| +++ b/gpu/ipc/service/child_window_surface_win.cc |
| @@ -7,6 +7,8 @@ |
| #include <memory> |
| #include "base/compiler_specific.h" |
| +#include "base/memory/ptr_util.h" |
| +#include "base/threading/thread.h" |
| #include "base/win/scoped_hdc.h" |
| #include "base/win/wrapped_window_proc.h" |
| #include "gpu/ipc/common/gpu_messages.h" |
| @@ -22,6 +24,16 @@ |
| namespace gpu { |
| +// This owns the thread and contains data that's shared between the threads. |
| +struct SharedData { |
| + SharedData() : thread("Window owner thread") {} |
| + |
| + base::Lock rect_lock; |
| + gfx::Rect rect_to_clear; |
| + |
| + base::Thread thread; |
| +}; |
| + |
| namespace { |
| ATOM g_window_class; |
| @@ -37,15 +49,13 @@ LRESULT CALLBACK IntermediateWindowProc(HWND window, |
| case WM_PAINT: |
| PAINTSTRUCT paint; |
| if (BeginPaint(window, &paint)) { |
| - ChildWindowSurfaceWin* window_surface = |
| - reinterpret_cast<ChildWindowSurfaceWin*>( |
| - gfx::GetWindowUserData(window)); |
| - DCHECK(window_surface); |
| - |
| - // Wait to clear the contents until a GL draw occurs, as otherwise an |
| - // unsightly black flash may happen if the GL contents are still |
| - // transparent. |
| - window_surface->InvalidateWindowRect(gfx::Rect(paint.rcPaint)); |
| + SharedData* shared_data = |
| + reinterpret_cast<SharedData*>(gfx::GetWindowUserData(window)); |
| + DCHECK(shared_data); |
| + |
| + base::AutoLock lock(shared_data->rect_lock); |
| + shared_data->rect_to_clear.Union(gfx::Rect(paint.rcPaint)); |
|
stanisc
2016/08/04 02:03:35
Should the lock scope end after this line?
jbauman
2016/08/04 20:45:51
Done.
|
| + |
| EndPaint(window, &paint); |
| } |
| return 0; |
| @@ -70,6 +80,34 @@ void InitializeWindowClass() { |
| return; |
| } |
| } |
| + |
| +void CreateChildWindow(HWND parent, |
|
stanisc
2016/08/04 02:03:35
It would be good to indicate in comments which thr
jbauman
2016/08/04 20:45:51
Done.
|
| + base::WaitableEvent* event, |
| + SharedData* shared_data, |
|
stanisc
2016/08/04 02:03:35
Should this be const pointer?
jbauman
2016/08/04 20:45:51
No, SetWindowUserData takes a non-const pointer.
|
| + HWND* result) { |
| + InitializeWindowClass(); |
| + DCHECK(g_window_class); |
| + |
| + RECT windowRect; |
| + GetClientRect(parent, &windowRect); |
| + |
| + HWND window = CreateWindowEx( |
| + WS_EX_NOPARENTNOTIFY, reinterpret_cast<wchar_t*>(g_window_class), L"", |
| + WS_CHILDWINDOW | WS_DISABLED | WS_VISIBLE, 0, 0, |
| + windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, |
| + ui::GetHiddenWindow(), NULL, NULL, NULL); |
| + *result = window; |
| + gfx::SetWindowUserData(window, shared_data); |
| + event->Signal(); |
| +} |
| + |
| +void DestroySharedData(std::unique_ptr<SharedData> shared_data) { |
| + shared_data->thread.Stop(); |
| +} |
| + |
| +void DestroyWindowOnThread(HWND window) { |
| + DestroyWindow(window); |
| +} |
| } |
|
stanisc
2016/08/04 02:03:35
Add // namespace
jbauman
2016/08/04 20:45:51
Done.
|
| ChildWindowSurfaceWin::ChildWindowSurfaceWin(GpuChannelManager* manager, |
| @@ -117,18 +155,19 @@ EGLConfig ChildWindowSurfaceWin::GetConfig() { |
| bool ChildWindowSurfaceWin::InitializeNativeWindow() { |
| if (window_) |
| return true; |
| - InitializeWindowClass(); |
| - DCHECK(g_window_class); |
| - RECT windowRect; |
| - GetClientRect(parent_window_, &windowRect); |
| + shared_data_ = base::MakeUnique<SharedData>(); |
| + |
| + base::Thread::Options options(base::MessageLoop::TYPE_UI, 0); |
| + shared_data_->thread.StartWithOptions(options); |
| + |
| + base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| + base::WaitableEvent::InitialState::NOT_SIGNALED); |
| + shared_data_->thread.task_runner()->PostTask( |
| + FROM_HERE, base::Bind(&CreateChildWindow, parent_window_, &event, |
| + shared_data_.get(), &window_)); |
| + event.Wait(); |
| - window_ = CreateWindowEx( |
| - WS_EX_NOPARENTNOTIFY, reinterpret_cast<wchar_t*>(g_window_class), L"", |
| - WS_CHILDWINDOW | WS_DISABLED | WS_VISIBLE, 0, 0, |
| - windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, |
| - ui::GetHiddenWindow(), NULL, NULL, NULL); |
| - gfx::SetWindowUserData(window_, this); |
| manager_->delegate()->SendAcceleratedSurfaceCreatedChildWindow(parent_window_, |
| window_); |
| return true; |
| @@ -205,26 +244,28 @@ gfx::SwapResult ChildWindowSurfaceWin::PostSubBuffer(int x, |
| return result; |
| } |
| -void ChildWindowSurfaceWin::InvalidateWindowRect(const gfx::Rect& rect) { |
| - rect_to_clear_.Union(rect); |
| -} |
| - |
| void ChildWindowSurfaceWin::ClearInvalidContents() { |
| - if (!rect_to_clear_.IsEmpty()) { |
| + base::AutoLock lock(shared_data_->rect_lock); |
| + if (!shared_data_->rect_to_clear.IsEmpty()) { |
| base::win::ScopedGetDC dc(window_); |
|
stanisc
2016/08/04 02:03:35
Is this running on the main thread?
Is it safe to
jbauman
2016/08/04 20:45:51
Yeah, it's fine to do GetDC on any thread (or even
|
| - RECT rect = rect_to_clear_.ToRECT(); |
| + RECT rect = shared_data_->rect_to_clear.ToRECT(); |
| // DirectComposition composites with the contents under the SwapChain, |
| // so ensure that's cleared. GDI treats black as transparent. |
| FillRect(dc, &rect, reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH))); |
| - rect_to_clear_ = gfx::Rect(); |
| + shared_data_->rect_to_clear = gfx::Rect(); |
| } |
| } |
| ChildWindowSurfaceWin::~ChildWindowSurfaceWin() { |
| - gfx::SetWindowUserData(window_, nullptr); |
| - DestroyWindow(window_); |
| + if (shared_data_) { |
| + scoped_refptr<base::TaskRunner> task_runner = |
| + shared_data_->thread.task_runner(); |
| + task_runner->PostTaskAndReply( |
| + FROM_HERE, base::Bind(&DestroyWindowOnThread, window_), |
| + base::Bind(&DestroySharedData, base::Passed(std::move(shared_data_)))); |
|
stanisc
2016/08/04 02:03:35
Clever solution!
|
| + } |
| } |
| } // namespace gpu |