Chromium Code Reviews| 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): Don't ignore other transforms and whatnot. | |
|
joth
2013/05/09 10:48:52
think you can remove this comment now.
| |
| 134 // TODO(boliu): Have a scoped var to unset this. | |
| 135 inside_draw_ = true; | |
| 136 | |
| 137 gfx::Transform transform; | |
| 138 transform.matrix().setColMajorf(draw_info->transform); | |
| 139 transform.Translate(hw_rendering_scroll_.x(), hw_rendering_scroll_.y()); | |
| 140 compositor_->DemandDrawHw( | |
| 141 gfx::Size(draw_info->width, draw_info->height), | |
| 142 transform, | |
| 143 gfx::Rect(draw_info->clip_left, | |
| 144 draw_info->clip_top, | |
| 145 draw_info->clip_right - draw_info->clip_left, | |
| 146 draw_info->clip_bottom - draw_info->clip_top)); | |
| 147 | |
| 148 inside_draw_ = false; | |
| 149 | |
| 150 // The GL functor must ensure these are set to zero before returning. | |
| 151 // Not setting them leads to graphical artifacts that can affect other apps. | |
| 152 glBindBuffer(GL_ARRAY_BUFFER, 0); | |
| 153 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | |
| 154 | |
| 155 if (continuous_invalidate_) | |
| 156 Invalidate(); | |
|
joth
2013/05/09 10:48:52
TODO: this should be PostTask to UI thread, to avo
| |
| 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 // TODO(boliu): Need invalidate here if visible? | |
|
joth
2013/05/09 10:48:52
fairly sure the framework will do this for you
| |
| 180 } | |
| 181 | |
| 182 void InProcessViewRenderer::OnSizeChanged(int width, int height) { | |
| 183 } | |
| 184 | |
| 185 void InProcessViewRenderer::OnAttachedToWindow(int width, int height) { | |
| 186 } | |
| 187 | |
| 188 void InProcessViewRenderer::OnDetachedFromWindow() { | |
| 189 } | |
| 190 | |
| 191 bool InProcessViewRenderer::IsAttachedToWindow() { | |
| 192 return false; | |
| 193 } | |
| 194 | |
| 195 bool InProcessViewRenderer::IsViewVisible() { | |
| 196 return view_visible_; | |
| 197 } | |
| 198 | |
| 199 gfx::Rect InProcessViewRenderer::GetScreenRect() { | |
| 200 return gfx::Rect(); | |
| 201 } | |
| 202 | |
| 37 void InProcessViewRenderer::DidDestroyCompositor( | 203 void InProcessViewRenderer::DidDestroyCompositor( |
| 38 content::SynchronousCompositor* compositor) { | 204 content::SynchronousCompositor* compositor) { |
| 39 // Allow for transient hand-over when two compositors may reference | 205 // Allow for transient hand-over when two compositors may reference |
| 40 // a single client. | 206 // a single client. |
| 41 if (compositor_ == compositor) | 207 if (compositor_ == compositor) |
| 42 compositor_ = NULL; | 208 compositor_ = NULL; |
| 43 } | 209 } |
| 44 | 210 |
| 211 void InProcessViewRenderer::SetContinuousInvalidate(bool invalidate) { | |
| 212 if (continuous_invalidate_ == invalidate) | |
| 213 return; | |
| 214 | |
| 215 continuous_invalidate_ = invalidate; | |
| 216 // TODO(boliu): Handle if not attached to window case. | |
| 217 if (continuous_invalidate_ && !inside_draw_) | |
| 218 Invalidate(); | |
| 219 } | |
| 220 | |
| 221 void InProcessViewRenderer::Invalidate() { | |
| 222 DCHECK(view_visible_); | |
| 223 client_->Invalidate(); | |
| 224 } | |
| 225 | |
| 45 } // namespace android_webview | 226 } // namespace android_webview |
| OLD | NEW |