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 362e182b9f82e6b05c7c4beb893d5bf0d3fa7717..762fbd117391233704e07375d64474912e305e1c 100644 |
--- a/gpu/ipc/service/child_window_surface_win.cc |
+++ b/gpu/ipc/service/child_window_surface_win.cc |
@@ -7,8 +7,6 @@ |
#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" |
@@ -24,21 +22,10 @@ |
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; |
-// This runs on the window owner thread. |
LRESULT CALLBACK IntermediateWindowProc(HWND window, |
UINT message, |
WPARAM w_param, |
@@ -50,14 +37,15 @@ |
case WM_PAINT: |
PAINTSTRUCT paint; |
if (BeginPaint(window, &paint)) { |
- 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)); |
- } |
- |
+ 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)); |
EndPaint(window, &paint); |
} |
return 0; |
@@ -66,7 +54,6 @@ |
} |
} |
-// This runs on the window owner thread. |
void InitializeWindowClass() { |
if (g_window_class) |
return; |
@@ -83,40 +70,7 @@ |
return; |
} |
} |
- |
-// This runs on the window owner thread. |
-void CreateChildWindow(HWND parent, |
- base::WaitableEvent* event, |
- SharedData* shared_data, |
- 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(); |
-} |
- |
-// This runs on the main thread after the window was destroyed on window owner |
-// thread. |
-void DestroySharedData(std::unique_ptr<SharedData> shared_data) { |
- shared_data->thread.Stop(); |
-} |
- |
-// This runs on the window owner thread. |
-void DestroyWindowOnThread(HWND window) { |
- DestroyWindow(window); |
-} |
- |
-} // namespace |
+} |
ChildWindowSurfaceWin::ChildWindowSurfaceWin(GpuChannelManager* manager, |
HWND parent_window) |
@@ -163,19 +117,18 @@ |
bool ChildWindowSurfaceWin::InitializeNativeWindow() { |
if (window_) |
return true; |
- |
- 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(); |
- |
+ InitializeWindowClass(); |
+ DCHECK(g_window_class); |
+ |
+ RECT windowRect; |
+ GetClientRect(parent_window_, &windowRect); |
+ |
+ 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; |
@@ -252,28 +205,26 @@ |
return result; |
} |
+void ChildWindowSurfaceWin::InvalidateWindowRect(const gfx::Rect& rect) { |
+ rect_to_clear_.Union(rect); |
+} |
+ |
void ChildWindowSurfaceWin::ClearInvalidContents() { |
- base::AutoLock lock(shared_data_->rect_lock); |
- if (!shared_data_->rect_to_clear.IsEmpty()) { |
+ if (!rect_to_clear_.IsEmpty()) { |
base::win::ScopedGetDC dc(window_); |
- RECT rect = shared_data_->rect_to_clear.ToRECT(); |
+ RECT rect = 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))); |
- shared_data_->rect_to_clear = gfx::Rect(); |
+ rect_to_clear_ = gfx::Rect(); |
} |
} |
ChildWindowSurfaceWin::~ChildWindowSurfaceWin() { |
- 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_)))); |
- } |
+ gfx::SetWindowUserData(window_, nullptr); |
+ DestroyWindow(window_); |
} |
} // namespace gpu |