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

Side by Side Diff: content/common/gpu/child_window_surface_win.cc

Issue 1845563005: Refactor content/common/gpu into gpu/ipc/service (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Drop ref to deleted content_tests_gypi_values.content_unittests_ozone_sources Created 4 years, 8 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 unified diff | Download patch
« no previous file with comments | « content/common/gpu/child_window_surface_win.h ('k') | content/common/gpu/gpu_channel.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "content/common/gpu/child_window_surface_win.h"
6
7 #include "base/compiler_specific.h"
8 #include "base/win/scoped_hdc.h"
9 #include "base/win/wrapped_window_proc.h"
10 #include "content/common/gpu/gpu_channel_manager.h"
11 #include "content/common/gpu/gpu_channel_manager_delegate.h"
12 #include "gpu/ipc/common/gpu_messages.h"
13 #include "ui/base/win/hidden_window.h"
14 #include "ui/gfx/native_widget_types.h"
15 #include "ui/gfx/win/hwnd_util.h"
16 #include "ui/gl/egl_util.h"
17 #include "ui/gl/gl_context.h"
18 #include "ui/gl/gl_surface_egl.h"
19 #include "ui/gl/scoped_make_current.h"
20
21 namespace content {
22
23 namespace {
24
25 ATOM g_window_class;
26
27 LRESULT CALLBACK IntermediateWindowProc(HWND window,
28 UINT message,
29 WPARAM w_param,
30 LPARAM l_param) {
31 switch (message) {
32 case WM_ERASEBKGND:
33 // Prevent windows from erasing the background.
34 return 1;
35 case WM_PAINT:
36 PAINTSTRUCT paint;
37 if (BeginPaint(window, &paint)) {
38 ChildWindowSurfaceWin* window_surface =
39 reinterpret_cast<ChildWindowSurfaceWin*>(
40 gfx::GetWindowUserData(window));
41 DCHECK(window_surface);
42
43 // Wait to clear the contents until a GL draw occurs, as otherwise an
44 // unsightly black flash may happen if the GL contents are still
45 // transparent.
46 window_surface->InvalidateWindowRect(gfx::Rect(paint.rcPaint));
47 EndPaint(window, &paint);
48 }
49 return 0;
50 default:
51 return DefWindowProc(window, message, w_param, l_param);
52 }
53 }
54
55 void InitializeWindowClass() {
56 if (g_window_class)
57 return;
58
59 WNDCLASSEX intermediate_class;
60 base::win::InitializeWindowClass(
61 L"Intermediate D3D Window",
62 &base::win::WrappedWindowProc<IntermediateWindowProc>, CS_OWNDC, 0, 0,
63 nullptr, reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)), nullptr,
64 nullptr, nullptr, &intermediate_class);
65 g_window_class = RegisterClassEx(&intermediate_class);
66 if (!g_window_class) {
67 LOG(ERROR) << "RegisterClass failed.";
68 return;
69 }
70 }
71 }
72
73 ChildWindowSurfaceWin::ChildWindowSurfaceWin(GpuChannelManager* manager,
74 HWND parent_window)
75 : gfx::NativeViewGLSurfaceEGL(0),
76 parent_window_(parent_window),
77 manager_(manager),
78 alpha_(true),
79 first_swap_(true) {
80 // Don't use EGL_ANGLE_window_fixed_size so that we can avoid recreating the
81 // window surface, which can cause flicker on DirectComposition.
82 enable_fixed_size_angle_ = false;
83 }
84
85 EGLConfig ChildWindowSurfaceWin::GetConfig() {
86 if (!config_) {
87 int alpha_size = alpha_ ? 8 : EGL_DONT_CARE;
88
89 EGLint config_attribs[] = {EGL_ALPHA_SIZE,
90 alpha_size,
91 EGL_BLUE_SIZE,
92 8,
93 EGL_GREEN_SIZE,
94 8,
95 EGL_RED_SIZE,
96 8,
97 EGL_RENDERABLE_TYPE,
98 EGL_OPENGL_ES2_BIT,
99 EGL_SURFACE_TYPE,
100 EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
101 EGL_NONE};
102
103 EGLDisplay display = GetHardwareDisplay();
104 EGLint num_configs;
105 if (!eglChooseConfig(display, config_attribs, &config_, 1, &num_configs)) {
106 LOG(ERROR) << "eglChooseConfig failed with error "
107 << ui::GetLastEGLErrorString();
108 return NULL;
109 }
110 }
111
112 return config_;
113 }
114
115 bool ChildWindowSurfaceWin::InitializeNativeWindow() {
116 if (window_)
117 return true;
118 InitializeWindowClass();
119 DCHECK(g_window_class);
120
121 RECT windowRect;
122 GetClientRect(parent_window_, &windowRect);
123
124 window_ = CreateWindowEx(
125 WS_EX_NOPARENTNOTIFY, reinterpret_cast<wchar_t*>(g_window_class), L"",
126 WS_CHILDWINDOW | WS_DISABLED | WS_VISIBLE, 0, 0,
127 windowRect.right - windowRect.left, windowRect.bottom - windowRect.top,
128 ui::GetHiddenWindow(), NULL, NULL, NULL);
129 gfx::SetWindowUserData(window_, this);
130 manager_->delegate()->SendAcceleratedSurfaceCreatedChildWindow(parent_window_,
131 window_);
132 return true;
133 }
134
135 bool ChildWindowSurfaceWin::Resize(const gfx::Size& size,
136 float scale_factor,
137 bool has_alpha) {
138 if (!SupportsPostSubBuffer()) {
139 if (!MoveWindow(window_, 0, 0, size.width(), size.height(), FALSE)) {
140 return false;
141 }
142 alpha_ = has_alpha;
143 return gfx::NativeViewGLSurfaceEGL::Resize(size, scale_factor, has_alpha);
144 } else {
145 if (size == GetSize() && has_alpha == alpha_)
146 return true;
147
148 // Force a resize and redraw (but not a move, activate, etc.).
149 if (!SetWindowPos(window_, nullptr, 0, 0, size.width(), size.height(),
150 SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOCOPYBITS |
151 SWP_NOOWNERZORDER | SWP_NOZORDER)) {
152 return false;
153 }
154 size_ = size;
155 if (has_alpha == alpha_) {
156 // A 0-size PostSubBuffer doesn't swap but forces the swap chain to resize
157 // to match the window.
158 PostSubBuffer(0, 0, 0, 0);
159 } else {
160 alpha_ = has_alpha;
161 config_ = nullptr;
162
163 scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current;
164 gfx::GLContext* current_context = gfx::GLContext::GetCurrent();
165 bool was_current = current_context && current_context->IsCurrent(this);
166 if (was_current) {
167 scoped_make_current.reset(
168 new ui::ScopedMakeCurrent(current_context, this));
169 current_context->ReleaseCurrent(this);
170 }
171
172 Destroy();
173
174 if (!Initialize()) {
175 LOG(ERROR) << "Failed to resize window.";
176 return false;
177 }
178 }
179 return true;
180 }
181 }
182
183 gfx::SwapResult ChildWindowSurfaceWin::SwapBuffers() {
184 gfx::SwapResult result = NativeViewGLSurfaceEGL::SwapBuffers();
185 // Force the driver to finish drawing before clearing the contents to
186 // transparent, to reduce or eliminate the period of time where the contents
187 // have flashed black.
188 if (first_swap_) {
189 glFinish();
190 first_swap_ = false;
191 }
192 ClearInvalidContents();
193 return result;
194 }
195
196 gfx::SwapResult ChildWindowSurfaceWin::PostSubBuffer(int x,
197 int y,
198 int width,
199 int height) {
200 gfx::SwapResult result =
201 NativeViewGLSurfaceEGL::PostSubBuffer(x, y, width, height);
202 ClearInvalidContents();
203 return result;
204 }
205
206 void ChildWindowSurfaceWin::InvalidateWindowRect(const gfx::Rect& rect) {
207 rect_to_clear_.Union(rect);
208 }
209
210 void ChildWindowSurfaceWin::ClearInvalidContents() {
211 if (!rect_to_clear_.IsEmpty()) {
212 base::win::ScopedGetDC dc(window_);
213
214 RECT rect = rect_to_clear_.ToRECT();
215
216 // DirectComposition composites with the contents under the SwapChain,
217 // so ensure that's cleared. GDI treats black as transparent.
218 FillRect(dc, &rect, reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)));
219 rect_to_clear_ = gfx::Rect();
220 }
221 }
222
223 ChildWindowSurfaceWin::~ChildWindowSurfaceWin() {
224 gfx::SetWindowUserData(window_, nullptr);
225 DestroyWindow(window_);
226 }
227
228 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/child_window_surface_win.h ('k') | content/common/gpu/gpu_channel.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698