| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "android_webview/browser/in_process_renderer/in_process_view_renderer.h
" | 5 #include "android_webview/browser/in_process_renderer/in_process_view_renderer.h
" |
| 6 | 6 |
| 7 #include "android_webview/public/browser/draw_gl.h" |
| 7 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "content/public/browser/android/content_view_core.h" |
| 10 #include "content/public/browser/render_view_host.h" |
| 11 #include "content/public/browser/web_contents.h" |
| 8 #include "content/public/renderer/android/synchronous_compositor.h" | 12 #include "content/public/renderer/android/synchronous_compositor.h" |
| 13 #include "ui/gfx/transform.h" |
| 14 #include "ui/gl/gl_bindings.h" |
| 9 | 15 |
| 10 namespace android_webview { | 16 namespace android_webview { |
| 11 | 17 |
| 18 namespace { |
| 19 const void* kUserDataKey = &kUserDataKey; |
| 20 |
| 21 class UserData : public content::WebContents::Data { |
| 22 public: |
| 23 UserData(InProcessViewRenderer* ptr) : instance_(ptr) {} |
| 24 virtual ~UserData() { |
| 25 instance_->WebContentsGone(); |
| 26 } |
| 27 |
| 28 static InProcessViewRenderer* GetInstance(content::WebContents* contents) { |
| 29 if (!contents) |
| 30 return NULL; |
| 31 UserData* data = reinterpret_cast<UserData*>( |
| 32 contents->GetUserData(kUserDataKey)); |
| 33 return data ? data->instance_ : NULL; |
| 34 } |
| 35 |
| 36 private: |
| 37 InProcessViewRenderer* instance_; |
| 38 }; |
| 39 |
| 40 } // namespace |
| 41 |
| 12 InProcessViewRenderer::InProcessViewRenderer( | 42 InProcessViewRenderer::InProcessViewRenderer( |
| 13 BrowserViewRenderer::Client* client, | 43 BrowserViewRenderer::Client* client, |
| 14 JavaHelper* java_helper) | 44 JavaHelper* java_helper) |
| 15 : BrowserViewRendererImpl(client, java_helper), | 45 : web_contents_(NULL), |
| 16 compositor_(NULL) { | 46 compositor_(NULL), |
| 47 client_(client), |
| 48 view_visible_(false), |
| 49 inside_draw_(false), |
| 50 continuous_invalidate_(false), |
| 51 last_frame_context_(NULL) { |
| 17 } | 52 } |
| 18 | 53 |
| 19 InProcessViewRenderer::~InProcessViewRenderer() { | 54 InProcessViewRenderer::~InProcessViewRenderer() { |
| 20 if (compositor_) | 55 if (compositor_) |
| 21 compositor_->SetClient(NULL); | 56 compositor_->SetClient(NULL); |
| 57 SetContents(NULL); |
| 58 } |
| 59 |
| 60 // static |
| 61 InProcessViewRenderer* InProcessViewRenderer::FromWebContents( |
| 62 content::WebContents* contents) { |
| 63 return UserData::GetInstance(contents); |
| 64 } |
| 65 |
| 66 // static |
| 67 InProcessViewRenderer* InProcessViewRenderer::FromId(int render_process_id, |
| 68 int render_view_id) { |
| 69 const content::RenderViewHost* rvh = |
| 70 content::RenderViewHost::FromID(render_process_id, render_view_id); |
| 71 if (!rvh) return NULL; |
| 72 return InProcessViewRenderer::FromWebContents( |
| 73 content::WebContents::FromRenderViewHost(rvh)); |
| 22 } | 74 } |
| 23 | 75 |
| 24 void InProcessViewRenderer::BindSynchronousCompositor( | 76 void InProcessViewRenderer::BindSynchronousCompositor( |
| 25 content::SynchronousCompositor* compositor) { | 77 content::SynchronousCompositor* compositor) { |
| 26 DCHECK(compositor && compositor_ != compositor); | 78 DCHECK(compositor && compositor_ != compositor); |
| 27 if (compositor_) | 79 if (compositor_) |
| 28 compositor_->SetClient(NULL); | 80 compositor_->SetClient(NULL); |
| 29 compositor_ = compositor; | 81 compositor_ = compositor; |
| 30 compositor_->SetClient(this); | 82 compositor_->SetClient(this); |
| 83 |
| 84 // TODO(boliu): If attached to window, ask java_helper_ to request |
| 85 // GL Initialization. |
| 86 } |
| 87 |
| 88 void InProcessViewRenderer::SetContents( |
| 89 content::ContentViewCore* content_view_core) { |
| 90 // First remove association from the prior ContentViewCore / WebContents. |
| 91 if (web_contents_) { |
| 92 web_contents_->SetUserData(kUserDataKey, NULL); |
| 93 DCHECK(!web_contents_); // WebContentsGone should have been called. |
| 94 } |
| 95 |
| 96 if (!content_view_core) |
| 97 return; |
| 98 |
| 99 web_contents_ = content_view_core->GetWebContents(); |
| 100 web_contents_->SetUserData(kUserDataKey, new UserData(this)); |
| 101 } |
| 102 |
| 103 void InProcessViewRenderer::WebContentsGone() { |
| 104 web_contents_ = NULL; |
| 31 } | 105 } |
| 32 | 106 |
| 33 bool InProcessViewRenderer::RenderPicture(SkCanvas* canvas) { | 107 bool InProcessViewRenderer::RenderPicture(SkCanvas* canvas) { |
| 34 return compositor_ && compositor_->DemandDrawSw(canvas); | 108 return compositor_ && compositor_->DemandDrawSw(canvas); |
| 35 } | 109 } |
| 36 | 110 |
| 111 void InProcessViewRenderer::DrawGL(AwDrawGLInfo* draw_info) { |
| 112 DCHECK(view_visible_); |
| 113 DCHECK_EQ(draw_info->mode, AwDrawGLInfo::kModeDraw); |
| 114 |
| 115 // We need to watch if the current Android context has changed and enforce |
| 116 // a clean-up in the compositor. |
| 117 EGLContext current_context = eglGetCurrentContext(); |
| 118 if (!current_context) { |
| 119 LOG(WARNING) << "No current context attached. Skipping composite."; |
| 120 return; |
| 121 } |
| 122 |
| 123 if (last_frame_context_ != current_context) { |
| 124 last_frame_context_ = current_context; |
| 125 // TODO(boliu): Handle context lost |
| 126 } |
| 127 |
| 128 // TODO(boliu): Make sure this is not called before compositor is initialized |
| 129 // and GL is ready. Then make this a DCHECK. |
| 130 if (!compositor_) |
| 131 return; |
| 132 |
| 133 // TODO(boliu): Have a scoped var to unset this. |
| 134 inside_draw_ = true; |
| 135 |
| 136 gfx::Transform transform; |
| 137 transform.matrix().setColMajorf(draw_info->transform); |
| 138 transform.Translate(hw_rendering_scroll_.x(), hw_rendering_scroll_.y()); |
| 139 compositor_->DemandDrawHw( |
| 140 gfx::Size(draw_info->width, draw_info->height), |
| 141 transform, |
| 142 gfx::Rect(draw_info->clip_left, |
| 143 draw_info->clip_top, |
| 144 draw_info->clip_right - draw_info->clip_left, |
| 145 draw_info->clip_bottom - draw_info->clip_top)); |
| 146 |
| 147 inside_draw_ = false; |
| 148 |
| 149 // The GL functor must ensure these are set to zero before returning. |
| 150 // Not setting them leads to graphical artifacts that can affect other apps. |
| 151 glBindBuffer(GL_ARRAY_BUFFER, 0); |
| 152 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); |
| 153 |
| 154 // TODO(boliu): Should post task to invalidate. |
| 155 if (continuous_invalidate_) |
| 156 Invalidate(); |
| 157 } |
| 158 |
| 159 void InProcessViewRenderer::SetScrollForHWFrame(int x, int y) { |
| 160 hw_rendering_scroll_ = gfx::Point(x, y); |
| 161 } |
| 162 |
| 163 bool InProcessViewRenderer::DrawSW(jobject java_canvas, |
| 164 const gfx::Rect& clip) { |
| 165 return false; |
| 166 } |
| 167 |
| 168 base::android::ScopedJavaLocalRef<jobject> |
| 169 InProcessViewRenderer::CapturePicture() { |
| 170 return base::android::ScopedJavaLocalRef<jobject>(); |
| 171 } |
| 172 |
| 173 void InProcessViewRenderer::EnableOnNewPicture(bool enabled) { |
| 174 } |
| 175 |
| 176 void InProcessViewRenderer::OnVisibilityChanged(bool view_visible, |
| 177 bool window_visible) { |
| 178 view_visible_ = window_visible && view_visible; |
| 179 } |
| 180 |
| 181 void InProcessViewRenderer::OnSizeChanged(int width, int height) { |
| 182 } |
| 183 |
| 184 void InProcessViewRenderer::OnAttachedToWindow(int width, int height) { |
| 185 } |
| 186 |
| 187 void InProcessViewRenderer::OnDetachedFromWindow() { |
| 188 } |
| 189 |
| 190 bool InProcessViewRenderer::IsAttachedToWindow() { |
| 191 return false; |
| 192 } |
| 193 |
| 194 bool InProcessViewRenderer::IsViewVisible() { |
| 195 return view_visible_; |
| 196 } |
| 197 |
| 198 gfx::Rect InProcessViewRenderer::GetScreenRect() { |
| 199 return gfx::Rect(); |
| 200 } |
| 201 |
| 37 void InProcessViewRenderer::DidDestroyCompositor( | 202 void InProcessViewRenderer::DidDestroyCompositor( |
| 38 content::SynchronousCompositor* compositor) { | 203 content::SynchronousCompositor* compositor) { |
| 39 // Allow for transient hand-over when two compositors may reference | 204 // Allow for transient hand-over when two compositors may reference |
| 40 // a single client. | 205 // a single client. |
| 41 if (compositor_ == compositor) | 206 if (compositor_ == compositor) |
| 42 compositor_ = NULL; | 207 compositor_ = NULL; |
| 43 } | 208 } |
| 44 | 209 |
| 210 void InProcessViewRenderer::SetContinuousInvalidate(bool invalidate) { |
| 211 if (continuous_invalidate_ == invalidate) |
| 212 return; |
| 213 |
| 214 continuous_invalidate_ = invalidate; |
| 215 // TODO(boliu): Handle if not attached to window case. |
| 216 if (continuous_invalidate_ && !inside_draw_) |
| 217 Invalidate(); |
| 218 } |
| 219 |
| 220 void InProcessViewRenderer::Invalidate() { |
| 221 DCHECK(view_visible_); |
| 222 client_->Invalidate(); |
| 223 } |
| 224 |
| 45 } // namespace android_webview | 225 } // namespace android_webview |
| OLD | NEW |