Add default implementations for AppWindowRegistry::Observer notifications.
[chromium-blink-merge.git] / android_webview / browser / hardware_renderer.cc
blobf1528ec8f8c7c73af78c824e8932792ced24dde1
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/hardware_renderer.h"
7 #include "android_webview/browser/aw_gl_surface.h"
8 #include "android_webview/browser/browser_view_renderer_client.h"
9 #include "android_webview/browser/scoped_app_gl_state_restore.h"
10 #include "android_webview/public/browser/draw_gl.h"
11 #include "base/debug/trace_event.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "content/public/browser/android/synchronous_compositor.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "gpu/command_buffer/service/shader_translator_cache.h"
16 #include "ui/gfx/geometry/rect_conversions.h"
17 #include "ui/gfx/geometry/rect_f.h"
18 #include "ui/gfx/transform.h"
20 namespace android_webview {
22 namespace {
24 base::LazyInstance<scoped_refptr<internal::DeferredGpuCommandService> >
25 g_service = LAZY_INSTANCE_INITIALIZER;
27 } // namespace
29 HardwareRenderer::HardwareRenderer(SharedRendererState* state)
30 : shared_renderer_state_(state),
31 last_egl_context_(eglGetCurrentContext()),
32 renderer_manager_key_(GLViewRendererManager::GetInstance()->PushBack(
33 shared_renderer_state_)) {
34 DCHECK(last_egl_context_);
35 if (!g_service.Get()) {
36 g_service.Get() = new internal::DeferredGpuCommandService;
37 content::SynchronousCompositor::SetGpuService(g_service.Get());
40 ScopedAppGLStateRestore state_restore(
41 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT);
42 internal::ScopedAllowGL allow_gl;
44 gl_surface_ = new AwGLSurface;
45 bool success =
46 shared_renderer_state_->GetCompositor()->
47 InitializeHwDraw(gl_surface_);
48 DCHECK(success);
51 HardwareRenderer::~HardwareRenderer() {
52 GLViewRendererManager* render_manager = GLViewRendererManager::GetInstance();
53 render_manager->Remove(renderer_manager_key_);
55 ScopedAppGLStateRestore state_restore(
56 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT);
57 internal::ScopedAllowGL allow_gl;
59 shared_renderer_state_->GetCompositor()->ReleaseHwDraw();
60 gl_surface_ = NULL;
63 bool HardwareRenderer::DrawGL(AwDrawGLInfo* draw_info, DrawGLResult* result) {
64 TRACE_EVENT0("android_webview", "HardwareRenderer::DrawGL");
65 GLViewRendererManager::GetInstance()->DidDrawGL(renderer_manager_key_);
67 // We need to watch if the current Android context has changed and enforce
68 // a clean-up in the compositor.
69 EGLContext current_context = eglGetCurrentContext();
70 if (!current_context) {
71 DLOG(ERROR) << "DrawGL called without EGLContext";
72 return false;
75 // TODO(boliu): Handle context loss.
76 if (last_egl_context_ != current_context)
77 DLOG(WARNING) << "EGLContextChanged";
79 ScopedAppGLStateRestore state_restore(ScopedAppGLStateRestore::MODE_DRAW);
80 internal::ScopedAllowGL allow_gl;
82 if (draw_info->mode != AwDrawGLInfo::kModeDraw)
83 return false;
85 // Should only need to access SharedRendererState in kModeDraw and kModeSync.
86 const DrawGLInput input = shared_renderer_state_->GetDrawGLInput();
87 SetCompositorMemoryPolicy();
89 gl_surface_->SetBackingFrameBufferObject(
90 state_restore.framebuffer_binding_ext());
92 gfx::Transform transform;
93 transform.matrix().setColMajorf(draw_info->transform);
94 transform.Translate(input.scroll_offset.x(), input.scroll_offset.y());
95 gfx::Rect clip_rect(draw_info->clip_left,
96 draw_info->clip_top,
97 draw_info->clip_right - draw_info->clip_left,
98 draw_info->clip_bottom - draw_info->clip_top);
100 gfx::Rect viewport(draw_info->width, draw_info->height);
101 if (!draw_info->is_layer) {
102 gfx::RectF view_rect(input.width, input.height);
103 transform.TransformRect(&view_rect);
104 viewport.Intersect(gfx::ToEnclosingRect(view_rect));
107 bool did_draw = shared_renderer_state_->GetCompositor()->
108 DemandDrawHw(
109 gfx::Size(draw_info->width, draw_info->height),
110 transform,
111 viewport,
112 clip_rect,
113 state_restore.stencil_enabled());
114 gl_surface_->ResetBackingFrameBufferObject();
116 if (did_draw) {
117 result->frame_id = input.frame_id;
118 result->clip_contains_visible_rect =
119 clip_rect.Contains(input.global_visible_rect);
121 return did_draw;
124 void HardwareRenderer::SetCompositorMemoryPolicy() {
125 if (shared_renderer_state_->IsMemoryPolicyDirty()) {
126 content::SynchronousCompositorMemoryPolicy policy =
127 shared_renderer_state_->GetMemoryPolicy();
128 // Memory policy is set by BrowserViewRenderer on UI thread.
129 shared_renderer_state_->GetCompositor()->SetMemoryPolicy(policy);
130 shared_renderer_state_->SetMemoryPolicyDirty(false);
134 namespace internal {
136 base::LazyInstance<base::ThreadLocalBoolean> ScopedAllowGL::allow_gl;
138 // static
139 bool ScopedAllowGL::IsAllowed() {
140 return allow_gl.Get().Get();
143 ScopedAllowGL::ScopedAllowGL() {
144 DCHECK(!allow_gl.Get().Get());
145 allow_gl.Get().Set(true);
147 if (g_service.Get())
148 g_service.Get()->RunTasks();
151 ScopedAllowGL::~ScopedAllowGL() { allow_gl.Get().Set(false); }
153 DeferredGpuCommandService::DeferredGpuCommandService() {}
155 DeferredGpuCommandService::~DeferredGpuCommandService() {
156 base::AutoLock lock(tasks_lock_);
157 DCHECK(tasks_.empty());
160 // static
161 void DeferredGpuCommandService::RequestProcessGLOnUIThread() {
162 SharedRendererState* renderer_state =
163 GLViewRendererManager::GetInstance()->GetMostRecentlyDrawn();
164 if (!renderer_state) {
165 LOG(ERROR) << "No hardware renderer. Deadlock likely";
166 return;
168 renderer_state->ClientRequestDrawGL();
171 // Called from different threads!
172 void DeferredGpuCommandService::ScheduleTask(const base::Closure& task) {
174 base::AutoLock lock(tasks_lock_);
175 tasks_.push(task);
177 if (ScopedAllowGL::IsAllowed()) {
178 RunTasks();
179 } else {
180 RequestProcessGLOnUIThread();
184 void DeferredGpuCommandService::ScheduleIdleWork(
185 const base::Closure& callback) {
186 // TODO(sievers): Should this do anything?
189 bool DeferredGpuCommandService::UseVirtualizedGLContexts() { return true; }
191 scoped_refptr<gpu::gles2::ShaderTranslatorCache>
192 DeferredGpuCommandService::shader_translator_cache() {
193 if (!shader_translator_cache_.get())
194 shader_translator_cache_ = new gpu::gles2::ShaderTranslatorCache;
195 return shader_translator_cache_;
198 void DeferredGpuCommandService::RunTasks() {
199 bool has_more_tasks;
201 base::AutoLock lock(tasks_lock_);
202 has_more_tasks = tasks_.size() > 0;
205 while (has_more_tasks) {
206 base::Closure task;
208 base::AutoLock lock(tasks_lock_);
209 task = tasks_.front();
210 tasks_.pop();
212 task.Run();
214 base::AutoLock lock(tasks_lock_);
215 has_more_tasks = tasks_.size() > 0;
220 void DeferredGpuCommandService::AddRef() const {
221 base::RefCountedThreadSafe<DeferredGpuCommandService>::AddRef();
224 void DeferredGpuCommandService::Release() const {
225 base::RefCountedThreadSafe<DeferredGpuCommandService>::Release();
228 } // namespace internal
230 } // namespace android_webview