Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(468)

Unified Diff: gpu/ipc/service/child_window_surface_win.cc

Issue 2208153002: Create GPU child window on new thread. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: make hidden window on main thread Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gpu/ipc/service/child_window_surface_win.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..682489619c150e631d84ff6b2a1e96143f8c78fd 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,10 +24,21 @@
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,
@@ -37,15 +50,14 @@ 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));
+ }
+
EndPaint(window, &paint);
}
return 0;
@@ -54,6 +66,7 @@ LRESULT CALLBACK IntermediateWindowProc(HWND window,
}
}
+// This runs on the window owner thread.
void InitializeWindowClass() {
if (g_window_class)
return;
@@ -70,8 +83,39 @@ void InitializeWindowClass() {
return;
}
}
+
+// This runs on the window owner thread.
+void CreateChildWindow(HWND hidden_window,
+ const gfx::Size& size,
+ base::WaitableEvent* event,
+ SharedData* shared_data,
+ HWND* result) {
+ InitializeWindowClass();
+ DCHECK(g_window_class);
+
+ HWND window = CreateWindowEx(
+ WS_EX_NOPARENTNOTIFY, reinterpret_cast<wchar_t*>(g_window_class), L"",
+ WS_CHILDWINDOW | WS_DISABLED | WS_VISIBLE, 0, 0, size.width(),
+ size.height(), hidden_window, NULL, NULL, NULL);
+ CHECK(window);
+ *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)
: gl::NativeViewGLSurfaceEGL(0),
@@ -117,18 +161,24 @@ 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);
+
+ RECT window_rect;
+ GetClientRect(parent_window_, &window_rect);
+
+ shared_data_->thread.task_runner()->PostTask(
+ FROM_HERE, base::Bind(&CreateChildWindow, ui::GetHiddenWindow(),
+ gfx::Rect(window_rect).size(), &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 +255,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_);
- 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_))));
+ }
}
} // namespace gpu
« no previous file with comments | « gpu/ipc/service/child_window_surface_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698