Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / android_webview / browser / test / fake_window.cc
blobb55950461c33a824059d6bf1b8be82e4dca05ebb
1 // Copyright 2014 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.
5 #include "android_webview/browser/test/fake_window.h"
7 #include "android_webview/browser/browser_view_renderer.h"
8 #include "base/message_loop/message_loop_proxy.h"
9 #include "base/synchronization/waitable_event.h"
10 #include "base/threading/thread.h"
11 #include "ui/gl/gl_bindings.h"
13 namespace android_webview {
15 class FakeWindow::ScopedMakeCurrent {
16 public:
17 ScopedMakeCurrent(FakeWindow* view_root) : view_root_(view_root) {
18 DCHECK(!view_root_->context_current_);
19 view_root_->context_current_ = true;
20 bool result = view_root_->context_->MakeCurrent(view_root_->surface_.get());
21 DCHECK(result);
24 ~ScopedMakeCurrent() {
25 DCHECK(view_root_->context_current_);
26 view_root_->context_current_ = false;
28 // Release the underlying EGLContext. This is required because the real
29 // GLContextEGL may no longer be current here and to satisfy DCHECK in
30 // GLContextEGL::IsCurrent.
31 eglMakeCurrent(view_root_->surface_->GetDisplay(), EGL_NO_SURFACE,
32 EGL_NO_SURFACE, EGL_NO_CONTEXT);
33 view_root_->context_->ReleaseCurrent(view_root_->surface_.get());
36 private:
37 FakeWindow* view_root_;
40 FakeWindow::FakeWindow(BrowserViewRenderer* view,
41 WindowHooks* hooks,
42 gfx::Rect location)
43 : view_(view),
44 hooks_(hooks),
45 surface_size_(100, 100),
46 location_(location),
47 on_draw_hardware_pending_(false),
48 functor_(nullptr),
49 context_current_(false),
50 weak_ptr_factory_(this) {
51 CheckCurrentlyOnUIThread();
52 DCHECK(view_);
53 view_->OnAttachedToWindow(location_.width(), location_.height());
54 view_->SetWindowVisibility(true);
55 view_->SetViewVisibility(true);
58 FakeWindow::~FakeWindow() {
59 CheckCurrentlyOnUIThread();
62 void FakeWindow::Detach() {
63 CheckCurrentlyOnUIThread();
64 view_->OnDetachedFromWindow();
66 if (render_thread_loop_) {
67 base::WaitableEvent completion(true, false);
68 render_thread_loop_->PostTask(
69 FROM_HERE, base::Bind(&FakeWindow::DestroyOnRT, base::Unretained(this),
70 &completion));
71 completion.Wait();
74 render_thread_.reset();
75 functor_ = nullptr;
78 void FakeWindow::RequestDrawGL(bool wait_for_completion) {
79 CheckCurrentlyOnUIThread();
80 base::WaitableEvent completion(true, false);
81 render_thread_loop_->PostTask(
82 FROM_HERE,
83 base::Bind(&FakeWindow::ProcessFunctorOnRT, base::Unretained(this),
84 wait_for_completion ? &completion : nullptr));
85 if (wait_for_completion)
86 completion.Wait();
89 void FakeWindow::ProcessFunctorOnRT(base::WaitableEvent* sync) {
90 CheckCurrentlyOnRT();
91 AwDrawGLInfo process_info;
92 process_info.version = kAwDrawGLInfoVersion;
93 process_info.mode = AwDrawGLInfo::kModeProcess;
95 hooks_->WillProcessOnRT(functor_);
97 ScopedMakeCurrent make_current(this);
98 functor_->DrawGL(&process_info);
100 hooks_->DidProcessOnRT(functor_);
102 if (sync)
103 sync->Signal();
106 void FakeWindow::PostInvalidate() {
107 CheckCurrentlyOnUIThread();
108 if (on_draw_hardware_pending_)
109 return;
110 on_draw_hardware_pending_ = true;
111 base::MessageLoopProxy::current()->PostTask(
112 FROM_HERE,
113 base::Bind(&FakeWindow::OnDrawHardware, weak_ptr_factory_.GetWeakPtr()));
116 void FakeWindow::OnDrawHardware() {
117 CheckCurrentlyOnUIThread();
118 DCHECK(on_draw_hardware_pending_);
119 on_draw_hardware_pending_ = false;
121 view_->PrepareToDraw(gfx::Vector2d(), location_);
122 hooks_->WillOnDraw();
123 bool success = view_->OnDrawHardware();
124 hooks_->DidOnDraw(success);
125 if (success) {
126 CreateRenderThreadIfNeeded();
128 base::WaitableEvent completion(true, false);
129 render_thread_loop_->PostTask(
130 FROM_HERE, base::Bind(&FakeWindow::DrawFunctorOnRT,
131 base::Unretained(this), &completion));
132 completion.Wait();
136 void FakeWindow::DrawFunctorOnRT(base::WaitableEvent* sync) {
137 CheckCurrentlyOnRT();
138 // Ok to access UI functions until sync is signalled.
139 gfx::Rect location = location_;
141 AwDrawGLInfo process_info;
142 process_info.version = kAwDrawGLInfoVersion;
143 process_info.mode = AwDrawGLInfo::kModeSync;
145 hooks_->WillSyncOnRT(functor_);
146 functor_->DrawGL(&process_info);
147 hooks_->DidSyncOnRT(functor_);
149 sync->Signal();
151 AwDrawGLInfo draw_info;
152 draw_info.version = kAwDrawGLInfoVersion;
153 draw_info.mode = AwDrawGLInfo::kModeDraw;
154 draw_info.clip_left = location.x();
155 draw_info.clip_top = location.y();
156 draw_info.clip_right = location.x() + location.width();
157 draw_info.clip_bottom = location.y() + location.height();
159 if (!hooks_->WillDrawOnRT(functor_, &draw_info))
160 return;
163 ScopedMakeCurrent make_current(this);
164 functor_->DrawGL(&draw_info);
166 hooks_->DidDrawOnRT(functor_);
169 void FakeWindow::CheckCurrentlyOnUIThread() {
170 DCHECK(ui_checker_.CalledOnValidSequencedThread());
173 void FakeWindow::CreateRenderThreadIfNeeded() {
174 CheckCurrentlyOnUIThread();
175 if (functor_) {
176 DCHECK(render_thread_.get());
177 DCHECK(render_thread_loop_.get());
178 return;
180 functor_ = view_->GetAwDrawGLViewContext();
181 render_thread_.reset(new base::Thread("TestRenderThread"));
182 render_thread_->Start();
183 render_thread_loop_ = render_thread_->task_runner();
184 rt_checker_.DetachFromSequence();
186 base::WaitableEvent completion(true, false);
187 render_thread_loop_->PostTask(
188 FROM_HERE, base::Bind(&FakeWindow::InitializeOnRT, base::Unretained(this),
189 &completion));
190 completion.Wait();
193 void FakeWindow::InitializeOnRT(base::WaitableEvent* sync) {
194 CheckCurrentlyOnRT();
195 surface_ = gfx::GLSurface::CreateOffscreenGLSurface(surface_size_);
196 DCHECK(surface_.get());
197 DCHECK(surface_->GetHandle());
198 context_ = gfx::GLContext::CreateGLContext(nullptr, surface_.get(),
199 gfx::PreferDiscreteGpu);
200 DCHECK(context_.get());
201 sync->Signal();
204 void FakeWindow::DestroyOnRT(base::WaitableEvent* sync) {
205 CheckCurrentlyOnRT();
206 if (context_) {
207 DCHECK(!context_->IsCurrent(surface_.get()));
208 context_ = nullptr;
209 surface_ = nullptr;
211 sync->Signal();
214 void FakeWindow::CheckCurrentlyOnRT() {
215 DCHECK(rt_checker_.CalledOnValidSequencedThread());
218 } // namespace android_webview