| Index: android_webview/native/aw_contents.cc | 
| diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc | 
| index 7b429f23f0e51d0726b03870bc7aafd24b83a32e..6bef6903ba8e1e7f48ee5a186420538ca95b359b 100644 | 
| --- a/android_webview/native/aw_contents.cc | 
| +++ b/android_webview/native/aw_contents.cc | 
| @@ -4,32 +4,28 @@ | 
|  | 
| #include "android_webview/native/aw_contents.h" | 
|  | 
| -#include <android/bitmap.h> | 
| -#include <sys/system_properties.h> | 
| - | 
| #include "android_webview/browser/aw_browser_context.h" | 
| #include "android_webview/browser/aw_browser_main_parts.h" | 
| +#include "android_webview/browser/browser_view_renderer_impl.h" | 
| #include "android_webview/browser/net_disk_cache_remover.h" | 
| #include "android_webview/browser/renderer_host/aw_render_view_host_ext.h" | 
| #include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h" | 
| #include "android_webview/common/aw_hit_test_data.h" | 
| -#include "android_webview/common/renderer_picture_map.h" | 
| #include "android_webview/native/aw_browser_dependency_factory.h" | 
| #include "android_webview/native/aw_contents_io_thread_client_impl.h" | 
| #include "android_webview/native/aw_web_contents_delegate.h" | 
| +#include "android_webview/native/java_browser_view_renderer_helper.h" | 
| #include "android_webview/native/state_serializer.h" | 
| -#include "android_webview/public/browser/draw_sw.h" | 
| +#include "android_webview/public/browser/draw_gl.h" | 
| #include "base/android/jni_android.h" | 
| #include "base/android/jni_array.h" | 
| #include "base/android/jni_string.h" | 
| #include "base/bind.h" | 
| #include "base/callback.h" | 
| -#include "base/debug/trace_event.h" | 
| #include "base/message_loop.h" | 
| #include "base/pickle.h" | 
| #include "base/string16.h" | 
| #include "base/supports_user_data.h" | 
| -#include "cc/layer.h" | 
| #include "components/navigation_interception/intercept_navigation_delegate.h" | 
| #include "content/public/browser/android/content_view_core.h" | 
| #include "content/public/browser/browser_thread.h" | 
| @@ -41,25 +37,9 @@ | 
| #include "content/public/common/ssl_status.h" | 
| #include "jni/AwContents_jni.h" | 
| #include "net/base/x509_certificate.h" | 
| -#include "third_party/skia/include/core/SkBitmap.h" | 
| -#include "third_party/skia/include/core/SkCanvas.h" | 
| -#include "third_party/skia/include/core/SkDevice.h" | 
| -#include "third_party/skia/include/core/SkGraphics.h" | 
| -#include "third_party/skia/include/core/SkPicture.h" | 
| #include "ui/gfx/android/java_bitmap.h" | 
| -#include "ui/gfx/transform.h" | 
| -#include "ui/gl/gl_bindings.h" | 
| - | 
| -// TODO(leandrogracia): remove when crbug.com/164140 is closed. | 
| -// Borrowed from gl2ext.h. Cannot be included due to conflicts with | 
| -// gl_bindings.h and the EGL library methods (eglGetCurrentContext). | 
| -#ifndef GL_TEXTURE_EXTERNAL_OES | 
| -#define GL_TEXTURE_EXTERNAL_OES 0x8D65 | 
| -#endif | 
|  | 
| -#ifndef GL_TEXTURE_BINDING_EXTERNAL_OES | 
| -#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 | 
| -#endif | 
| +struct AwDrawSWFunctionTable; | 
|  | 
| using base::android::AttachCurrentThread; | 
| using base::android::ConvertJavaStringToUTF16; | 
| @@ -81,61 +61,16 @@ static void DrawGLFunction(int view_context, | 
| void* spare) { | 
| // |view_context| is the value that was returned from the java | 
| // AwContents.onPrepareDrawGL; this cast must match the code there. | 
| -  reinterpret_cast<android_webview::AwContents*>(view_context)->DrawGL( | 
| +  reinterpret_cast<android_webview::BrowserViewRenderer*>(view_context)->DrawGL( | 
| draw_info); | 
| } | 
| - | 
| -typedef base::Callback<bool(SkCanvas*)> RenderMethod; | 
| - | 
| -static bool RasterizeIntoBitmap(JNIEnv* env, | 
| -                                jobject jbitmap, | 
| -                                int scroll_x, | 
| -                                int scroll_y, | 
| -                                const RenderMethod& renderer) { | 
| -  DCHECK(jbitmap); | 
| - | 
| -  AndroidBitmapInfo bitmap_info; | 
| -  if (AndroidBitmap_getInfo(env, jbitmap, &bitmap_info) < 0) { | 
| -    LOG(WARNING) << "Error getting java bitmap info."; | 
| -    return false; | 
| -  } | 
| - | 
| -  void* pixels = NULL; | 
| -  if (AndroidBitmap_lockPixels(env, jbitmap, &pixels) < 0) { | 
| -    LOG(WARNING) << "Error locking java bitmap pixels."; | 
| -    return false; | 
| -  } | 
| - | 
| -  bool succeeded = false; | 
| -  { | 
| -    SkBitmap bitmap; | 
| -    bitmap.setConfig(SkBitmap::kARGB_8888_Config, | 
| -                     bitmap_info.width, | 
| -                     bitmap_info.height, | 
| -                     bitmap_info.stride); | 
| -    bitmap.setPixels(pixels); | 
| - | 
| -    SkDevice device(bitmap); | 
| -    SkCanvas canvas(&device); | 
| -    canvas.translate(-scroll_x, -scroll_y); | 
| -    succeeded = renderer.Run(&canvas); | 
| -  } | 
| - | 
| -  if (AndroidBitmap_unlockPixels(env, jbitmap) < 0) { | 
| -    LOG(WARNING) << "Error unlocking java bitmap pixels."; | 
| -    return false; | 
| -  } | 
| - | 
| -  return succeeded; | 
| -} | 
| } | 
|  | 
| namespace android_webview { | 
|  | 
| namespace { | 
|  | 
| -AwDrawSWFunctionTable* g_draw_sw_functions = NULL; | 
| -bool g_is_skia_version_compatible = false; | 
| +static JavaBrowserViewRendererHelper java_renderer_helper; | 
|  | 
| const void* kAwContentsUserDataKey = &kAwContentsUserDataKey; | 
|  | 
| @@ -180,13 +115,8 @@ AwContents::AwContents(JNIEnv* env, | 
| : java_ref_(env, obj), | 
| web_contents_delegate_( | 
| new AwWebContentsDelegate(env, web_contents_delegate)), | 
| -      view_visible_(false), | 
| -      compositor_visible_(false), | 
| -      is_composite_pending_(false), | 
| -      dpi_scale_(1.0f), | 
| -      on_new_picture_mode_(kOnNewPictureDisabled), | 
| -      last_frame_context_(NULL) { | 
| -  RendererPictureMap::CreateInstance(); | 
| +      ALLOW_THIS_IN_INITIALIZER_LIST(browser_view_renderer_( | 
| +          BrowserViewRendererImpl::Create(this, &java_renderer_helper))) { | 
| android_webview::AwBrowserDependencyFactory* dependency_factory = | 
| android_webview::AwBrowserDependencyFactory::GetInstance(); | 
|  | 
| @@ -196,12 +126,6 @@ AwContents::AwContents(JNIEnv* env, | 
| SetWebContents(dependency_factory->CreateWebContents()); | 
| } | 
|  | 
| -void AwContents::ResetCompositor() { | 
| -  compositor_.reset(content::Compositor::Create(this)); | 
| -  if (scissor_clip_layer_.get()) | 
| -    AttachLayerTree(); | 
| -} | 
| - | 
| void AwContents::SetWebContents(content::WebContents* web_contents) { | 
| web_contents_.reset(web_contents); | 
| if (find_helper_.get()) { | 
| @@ -211,11 +135,8 @@ void AwContents::SetWebContents(content::WebContents* web_contents) { | 
| icon_helper_->SetListener(this); | 
| web_contents_->SetUserData(kAwContentsUserDataKey, | 
| new AwContentsUserData(this)); | 
| - | 
| web_contents_->SetDelegate(web_contents_delegate_.get()); | 
| -  render_view_host_ext_.reset(new AwRenderViewHostExt(web_contents_.get(), | 
| -                              this)); | 
| -  ResetCompositor(); | 
| +  render_view_host_ext_.reset(new AwRenderViewHostExt(web_contents_.get())); | 
| } | 
|  | 
| void AwContents::SetWebContents(JNIEnv* env, jobject obj, jint new_wc) { | 
| @@ -231,287 +152,6 @@ AwContents::~AwContents() { | 
| icon_helper_->SetListener(NULL); | 
| } | 
|  | 
| -void AwContents::DrawGL(AwDrawGLInfo* draw_info) { | 
| - | 
| -  TRACE_EVENT0("AwContents", "AwContents::DrawGL"); | 
| - | 
| -  if (view_size_.IsEmpty() || !scissor_clip_layer_ || | 
| -      draw_info->mode == AwDrawGLInfo::kModeProcess) | 
| -    return; | 
| - | 
| -  DCHECK_EQ(draw_info->mode, AwDrawGLInfo::kModeDraw); | 
| - | 
| -  SetCompositorVisibility(view_visible_); | 
| -  if (!compositor_visible_) | 
| -    return; | 
| - | 
| -  // TODO(leandrogracia): remove when crbug.com/164140 is closed. | 
| -  // --------------------------------------------------------------------------- | 
| -  GLint texture_external_oes_binding; | 
| -  glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texture_external_oes_binding); | 
| - | 
| -  GLint vertex_array_buffer_binding; | 
| -  glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vertex_array_buffer_binding); | 
| - | 
| -  GLint index_array_buffer_binding; | 
| -  glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &index_array_buffer_binding); | 
| - | 
| -  GLint pack_alignment; | 
| -  glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment); | 
| - | 
| -  GLint unpack_alignment; | 
| -  glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpack_alignment); | 
| - | 
| -  struct { | 
| -    GLint enabled; | 
| -    GLint size; | 
| -    GLint type; | 
| -    GLint normalized; | 
| -    GLint stride; | 
| -    GLvoid* pointer; | 
| -  } vertex_attrib[3]; | 
| - | 
| -  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(vertex_attrib); ++i) { | 
| -    glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, | 
| -                        &vertex_attrib[i].enabled); | 
| -    glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, | 
| -                        &vertex_attrib[i].size); | 
| -    glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, | 
| -                        &vertex_attrib[i].type); | 
| -    glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, | 
| -                        &vertex_attrib[i].normalized); | 
| -    glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, | 
| -                        &vertex_attrib[i].stride); | 
| -    glGetVertexAttribPointerv(i, GL_VERTEX_ATTRIB_ARRAY_POINTER, | 
| -                        &vertex_attrib[i].pointer); | 
| -  } | 
| - | 
| -  GLboolean depth_test; | 
| -  glGetBooleanv(GL_DEPTH_TEST, &depth_test); | 
| - | 
| -  GLboolean cull_face; | 
| -  glGetBooleanv(GL_CULL_FACE, &cull_face); | 
| - | 
| -  GLboolean color_mask[4]; | 
| -  glGetBooleanv(GL_COLOR_WRITEMASK, color_mask); | 
| - | 
| -  GLboolean blend_enabled; | 
| -  glGetBooleanv(GL_BLEND, &blend_enabled); | 
| - | 
| -  GLint blend_src_rgb; | 
| -  glGetIntegerv(GL_BLEND_SRC_RGB, &blend_src_rgb); | 
| - | 
| -  GLint blend_src_alpha; | 
| -  glGetIntegerv(GL_BLEND_SRC_ALPHA, &blend_src_alpha); | 
| - | 
| -  GLint blend_dest_rgb; | 
| -  glGetIntegerv(GL_BLEND_DST_RGB, &blend_dest_rgb); | 
| - | 
| -  GLint blend_dest_alpha; | 
| -  glGetIntegerv(GL_BLEND_DST_ALPHA, &blend_dest_alpha); | 
| - | 
| -  GLint active_texture; | 
| -  glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture); | 
| - | 
| -  GLint viewport[4]; | 
| -  glGetIntegerv(GL_VIEWPORT, viewport); | 
| - | 
| -  GLboolean scissor_test; | 
| -  glGetBooleanv(GL_SCISSOR_TEST, &scissor_test); | 
| - | 
| -  GLint scissor_box[4]; | 
| -  glGetIntegerv(GL_SCISSOR_BOX, scissor_box); | 
| - | 
| -  GLint current_program; | 
| -  glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program); | 
| -  // --------------------------------------------------------------------------- | 
| - | 
| -  // We need to watch if the current Android context has changed and enforce | 
| -  // a clean-up in the compositor. | 
| -  EGLContext current_context = eglGetCurrentContext(); | 
| -  if (!current_context) { | 
| -    LOG(WARNING) << "No current context attached. Skipping composite."; | 
| -    return; | 
| -  } | 
| - | 
| -  if (last_frame_context_ != current_context) { | 
| -    if (last_frame_context_) | 
| -      ResetCompositor(); | 
| -    last_frame_context_ = current_context; | 
| -  } | 
| - | 
| -  compositor_->SetWindowBounds(gfx::Size(draw_info->width, draw_info->height)); | 
| - | 
| -  if (draw_info->is_layer) { | 
| -    // When rendering into a separate layer no view clipping, transform, | 
| -    // scissoring or background transparency need to be handled. | 
| -    // The Android framework will composite us afterwards. | 
| -    compositor_->SetHasTransparentBackground(false); | 
| -    view_clip_layer_->setMasksToBounds(false); | 
| -    transform_layer_->setTransform(gfx::Transform()); | 
| -    scissor_clip_layer_->setMasksToBounds(false); | 
| -    scissor_clip_layer_->setPosition(gfx::PointF()); | 
| -    scissor_clip_layer_->setBounds(gfx::Size()); | 
| -    scissor_clip_layer_->setSublayerTransform(gfx::Transform()); | 
| - | 
| -  } else { | 
| -    compositor_->SetHasTransparentBackground(true); | 
| - | 
| -    gfx::Rect clip_rect(draw_info->clip_left, draw_info->clip_top, | 
| -                        draw_info->clip_right - draw_info->clip_left, | 
| -                        draw_info->clip_bottom - draw_info->clip_top); | 
| - | 
| -    scissor_clip_layer_->setPosition(clip_rect.origin()); | 
| -    scissor_clip_layer_->setBounds(clip_rect.size()); | 
| -    scissor_clip_layer_->setMasksToBounds(true); | 
| - | 
| -    // The compositor clipping architecture enforces us to have the clip layer | 
| -    // as an ancestor of the area we want to clip, but this makes the transform | 
| -    // become relative to the clip area rather than the full surface. The clip | 
| -    // position offset needs to be undone before applying the transform. | 
| -    gfx::Transform undo_clip_position; | 
| -    undo_clip_position.Translate(-clip_rect.x(), -clip_rect.y()); | 
| -    scissor_clip_layer_->setSublayerTransform(undo_clip_position); | 
| - | 
| -    gfx::Transform transform; | 
| -    transform.matrix().setColMajorf(draw_info->transform); | 
| - | 
| -    // The scrolling values of the Android Framework affect the transformation | 
| -    // matrix. This needs to be undone to let the compositor handle scrolling. | 
| -    transform.Translate(hw_rendering_scroll_.x(), hw_rendering_scroll_.y()); | 
| -    transform_layer_->setTransform(transform); | 
| - | 
| -    view_clip_layer_->setMasksToBounds(true); | 
| -  } | 
| - | 
| -  compositor_->Composite(); | 
| -  is_composite_pending_ = false; | 
| - | 
| -  // TODO(leandrogracia): remove when crbug.com/164140 is closed. | 
| -  // --------------------------------------------------------------------------- | 
| -  char no_gl_restore_prop[PROP_VALUE_MAX]; | 
| -  __system_property_get("webview.chromium_no_gl_restore", no_gl_restore_prop); | 
| -  if (!strcmp(no_gl_restore_prop, "true")) { | 
| -    LOG(WARNING) << "Android GL functor not restoring the previous GL state."; | 
| -  } else { | 
| -    glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_external_oes_binding); | 
| -    glBindBuffer(GL_ARRAY_BUFFER, vertex_array_buffer_binding); | 
| -    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_buffer_binding); | 
| - | 
| -    glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment); | 
| -    glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment); | 
| - | 
| -    for (size_t i = 0; i < ARRAYSIZE_UNSAFE(vertex_attrib); ++i) { | 
| -      glVertexAttribPointer(i, vertex_attrib[i].size, | 
| -          vertex_attrib[i].type, vertex_attrib[i].normalized, | 
| -          vertex_attrib[i].stride, vertex_attrib[i].pointer); | 
| - | 
| -      if (vertex_attrib[i].enabled) | 
| -        glEnableVertexAttribArray(i); | 
| -      else | 
| -        glDisableVertexAttribArray(i); | 
| -    } | 
| - | 
| -    if (depth_test) | 
| -      glEnable(GL_DEPTH_TEST); | 
| -    else | 
| -      glDisable(GL_DEPTH_TEST); | 
| - | 
| -    if (cull_face) | 
| -      glEnable(GL_CULL_FACE); | 
| -    else | 
| -      glDisable(GL_CULL_FACE); | 
| - | 
| -    glColorMask(color_mask[0], color_mask[1], color_mask[2], | 
| -                       color_mask[3]); | 
| - | 
| -    if (blend_enabled) | 
| -      glEnable(GL_BLEND); | 
| -    else | 
| -      glDisable(GL_BLEND); | 
| - | 
| -    glBlendFuncSeparate(blend_src_rgb, blend_dest_rgb, | 
| -                               blend_src_alpha, blend_dest_alpha); | 
| - | 
| -    glActiveTexture(active_texture); | 
| - | 
| -    glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); | 
| - | 
| -    if (scissor_test) | 
| -      glEnable(GL_SCISSOR_TEST); | 
| -    else | 
| -      glDisable(GL_SCISSOR_TEST); | 
| - | 
| -    glScissor(scissor_box[0], scissor_box[1], scissor_box[2], | 
| -                     scissor_box[3]); | 
| - | 
| -    glUseProgram(current_program); | 
| -  } | 
| -  // --------------------------------------------------------------------------- | 
| -} | 
| - | 
| -bool AwContents::DrawSW(JNIEnv* env, | 
| -                        jobject obj, | 
| -                        jobject java_canvas, | 
| -                        jint clip_x, | 
| -                        jint clip_y, | 
| -                        jint clip_w, | 
| -                        jint clip_h) { | 
| -  TRACE_EVENT0("AwContents", "AwContents::DrawSW"); | 
| - | 
| -  if (clip_w <= 0 || clip_h <= 0) | 
| -    return true; | 
| - | 
| -  AwPixelInfo* pixels; | 
| - | 
| -  // Render into an auxiliary bitmap if pixel info is not available. | 
| -  if (!g_draw_sw_functions || | 
| -      (pixels = g_draw_sw_functions->access_pixels(env, java_canvas)) == NULL) { | 
| -    ScopedJavaLocalRef<jobject> jbitmap(Java_AwContents_createBitmap( | 
| -        env, clip_w, clip_h)); | 
| -    if (!jbitmap.obj()) | 
| -      return false; | 
| - | 
| -    if (!RasterizeIntoBitmap(env, jbitmap.obj(), clip_x, clip_y, | 
| -        base::Bind(&AwContents::RenderSW, base::Unretained(this)))) | 
| -      return false; | 
| - | 
| -    Java_AwContents_drawBitmapIntoCanvas(env, jbitmap.obj(), java_canvas); | 
| -    return true; | 
| -  } | 
| - | 
| -  // Draw in a SkCanvas built over the pixel information. | 
| -  bool succeeded = false; | 
| -  { | 
| -    SkBitmap bitmap; | 
| -    bitmap.setConfig(static_cast<SkBitmap::Config>(pixels->config), | 
| -                     pixels->width, | 
| -                     pixels->height, | 
| -                     pixels->row_bytes); | 
| -    bitmap.setPixels(pixels->pixels); | 
| -    SkDevice device(bitmap); | 
| -    SkCanvas canvas(&device); | 
| -    SkMatrix matrix; | 
| -    for (int i = 0; i < 9; i++) | 
| -      matrix.set(i, pixels->matrix[i]); | 
| -    canvas.setMatrix(matrix); | 
| - | 
| -    SkRegion clip; | 
| -    if (pixels->clip_region_size) { | 
| -      size_t bytes_read = clip.readFromMemory(pixels->clip_region); | 
| -      DCHECK_EQ(pixels->clip_region_size, bytes_read); | 
| -      canvas.setClipRegion(clip); | 
| -    } else { | 
| -      clip.setRect(SkIRect::MakeWH(pixels->width, pixels->height)); | 
| -    } | 
| - | 
| -    succeeded = RenderSW(&canvas); | 
| -  } | 
| - | 
| -  g_draw_sw_functions->release_pixels(pixels); | 
| -  return succeeded; | 
| -} | 
| - | 
| jint AwContents::GetWebContents(JNIEnv* env, jobject obj) { | 
| return reinterpret_cast<jint>(web_contents_.get()); | 
| } | 
| @@ -520,30 +160,7 @@ void AwContents::DidInitializeContentViewCore(JNIEnv* env, jobject obj, | 
| jint content_view_core) { | 
| ContentViewCore* core = reinterpret_cast<ContentViewCore*>(content_view_core); | 
| DCHECK(core == ContentViewCore::FromWebContents(web_contents_.get())); | 
| - | 
| -  dpi_scale_ = core->GetDpiScale(); | 
| - | 
| -  // Ensures content keeps clipped within the view during transformations. | 
| -  view_clip_layer_ = cc::Layer::create(); | 
| -  view_clip_layer_->setBounds(view_size_); | 
| -  view_clip_layer_->addChild(core->GetLayer()); | 
| - | 
| -  // Applies the transformation matrix. | 
| -  transform_layer_ = cc::Layer::create(); | 
| -  transform_layer_->addChild(view_clip_layer_); | 
| - | 
| -  // Ensures content is drawn within the scissor clip rect provided by the | 
| -  // Android framework. | 
| -  scissor_clip_layer_ = cc::Layer::create(); | 
| -  scissor_clip_layer_->addChild(transform_layer_); | 
| - | 
| -  AttachLayerTree(); | 
| -} | 
| - | 
| -void AwContents::AttachLayerTree() { | 
| -  DCHECK(scissor_clip_layer_.get()); | 
| -  compositor_->SetRootLayer(scissor_clip_layer_); | 
| -  Invalidate(); | 
| +  browser_view_renderer_->SetContents(core); | 
| } | 
|  | 
| void AwContents::Destroy(JNIEnv* env, jobject obj) { | 
| @@ -552,12 +169,8 @@ void AwContents::Destroy(JNIEnv* env, jobject obj) { | 
|  | 
| // static | 
| void SetAwDrawSWFunctionTable(JNIEnv* env, jclass, jint function_table) { | 
| -  g_draw_sw_functions = | 
| -      reinterpret_cast<AwDrawSWFunctionTable*>(function_table); | 
| -  g_is_skia_version_compatible = | 
| -     g_draw_sw_functions->is_skia_version_compatible(&SkGraphics::GetVersion); | 
| -  LOG_IF(WARNING, !g_is_skia_version_compatible) << | 
| -      "Skia native versions are not compatible."; | 
| +  BrowserViewRendererImpl::SetAwDrawSWFunctionTable( | 
| +      reinterpret_cast<AwDrawSWFunctionTable*>(function_table)); | 
| } | 
|  | 
| // static | 
| @@ -565,6 +178,10 @@ jint GetAwDrawGLFunction(JNIEnv* env, jclass) { | 
| return reinterpret_cast<jint>(&DrawGLFunction); | 
| } | 
|  | 
| +jint AwContents::GetAwDrawGLViewContext(JNIEnv* env, jobject obj) { | 
| +  return reinterpret_cast<jint>(browser_view_renderer_.get()); | 
| +} | 
| + | 
| namespace { | 
| void DocumentHasImagesCallback(const ScopedJavaGlobalRef<jobject>& message, | 
| bool has_images) { | 
| @@ -890,39 +507,18 @@ void AwContents::OnReceivedTouchIconUrl(const std::string& url, | 
| env, obj.obj(), ConvertUTF8ToJavaString(env, url).obj(), precomposed); | 
| } | 
|  | 
| -void AwContents::ScheduleComposite() { | 
| -  TRACE_EVENT0("AwContents", "AwContents::ScheduleComposite"); | 
| - | 
| -  if (is_composite_pending_) | 
| -    return; | 
| - | 
| -  is_composite_pending_ = true; | 
| -  Invalidate(); | 
| -} | 
| - | 
| void AwContents::Invalidate() { | 
| JNIEnv* env = AttachCurrentThread(); | 
| ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); | 
| -  if (obj.is_null()) | 
| -    return; | 
| - | 
| -  if (view_visible_) | 
| +  if (!obj.is_null()) | 
| Java_AwContents_invalidate(env, obj.obj()); | 
| - | 
| -  // When not in invalidation-only mode onNewPicture will be triggered | 
| -  // from the OnPictureUpdated callback. | 
| -  if (on_new_picture_mode_ == kOnNewPictureInvalidationOnly) | 
| -    Java_AwContents_onNewPicture(env, obj.obj(), NULL); | 
| -} | 
| - | 
| -void AwContents::SetCompositorVisibility(bool visible) { | 
| -  if (compositor_visible_ != visible) { | 
| -    compositor_visible_ = visible; | 
| -    compositor_->SetVisible(compositor_visible_); | 
| -  } | 
| } | 
|  | 
| -void AwContents::OnSwapBuffersCompleted() { | 
| +void AwContents::OnNewPicture(const JavaRef<jobject>& picture) { | 
| +  JNIEnv* env = AttachCurrentThread(); | 
| +  ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); | 
| +  if (!obj.is_null()) | 
| +    Java_AwContents_onNewPicture(env, obj.obj(), picture.obj()); | 
| } | 
|  | 
| base::android::ScopedJavaLocalRef<jbyteArray> | 
| @@ -986,27 +582,21 @@ void AwContents::UpdateLastHitTestData(JNIEnv* env, jobject obj) { | 
|  | 
| void AwContents::OnSizeChanged(JNIEnv* env, jobject obj, | 
| int w, int h, int ow, int oh) { | 
| -  view_size_ = gfx::Size(w, h); | 
| -  if (view_clip_layer_.get()) | 
| -    view_clip_layer_->setBounds(view_size_); | 
| +  browser_view_renderer_->OnSizeChanged(w, h); | 
| } | 
|  | 
| void AwContents::SetWindowViewVisibility(JNIEnv* env, jobject obj, | 
| bool window_visible, | 
| bool view_visible) { | 
| -  view_visible_ = window_visible && view_visible; | 
| -  Invalidate(); | 
| +  browser_view_renderer_->OnVisibilityChanged(window_visible, view_visible); | 
| } | 
|  | 
| void AwContents::OnAttachedToWindow(JNIEnv* env, jobject obj, int w, int h) { | 
| -  view_size_ = gfx::Size(w, h); | 
| -  if (view_clip_layer_.get()) | 
| -    view_clip_layer_->setBounds(view_size_); | 
| +  browser_view_renderer_->OnAttachedToWindow(w, h); | 
| } | 
|  | 
| void AwContents::OnDetachedFromWindow(JNIEnv* env, jobject obj) { | 
| -  view_visible_ = false; | 
| -  SetCompositorVisibility(false); | 
| +  browser_view_renderer_->OnDetachedFromWindow(); | 
| } | 
|  | 
| base::android::ScopedJavaLocalRef<jbyteArray> | 
| @@ -1039,9 +629,20 @@ jboolean AwContents::RestoreFromOpaqueState( | 
| return RestoreFromPickle(&iterator, web_contents_.get()); | 
| } | 
|  | 
| +bool AwContents::DrawSW(JNIEnv* env, | 
| +                        jobject obj, | 
| +                        jobject canvas, | 
| +                        jint clip_x, | 
| +                        jint clip_y, | 
| +                        jint clip_w, | 
| +                        jint clip_h) { | 
| +  return browser_view_renderer_->DrawSW( | 
| +      canvas, gfx::Rect(clip_x, clip_y, clip_w, clip_h)); | 
| +} | 
| + | 
| void AwContents::SetScrollForHWFrame(JNIEnv* env, jobject obj, | 
| int scroll_x, int scroll_y) { | 
| -  hw_rendering_scroll_ = gfx::Point(scroll_x, scroll_y); | 
| +  browser_view_renderer_->SetScrollForHWFrame(scroll_x, scroll_y); | 
| } | 
|  | 
| void AwContents::SetPendingWebContentsForPopup( | 
| @@ -1066,106 +667,22 @@ jint AwContents::ReleasePopupWebContents(JNIEnv* env, jobject obj) { | 
|  | 
| ScopedJavaLocalRef<jobject> AwContents::CapturePicture(JNIEnv* env, | 
| jobject obj) { | 
| -  skia::RefPtr<SkPicture> picture = GetLastCapturedPicture(); | 
| -  if (!picture || !g_draw_sw_functions) | 
| -    return ScopedJavaLocalRef<jobject>(); | 
| - | 
| -  if (g_is_skia_version_compatible) | 
| -    return ScopedJavaLocalRef<jobject>(env, | 
| -        g_draw_sw_functions->create_picture(env, picture->clone())); | 
| - | 
| -  // If Skia versions are not compatible, workaround it by rasterizing the | 
| -  // picture into a bitmap and drawing it into a new Java picture. | 
| -  ScopedJavaLocalRef<jobject> jbitmap(Java_AwContents_createBitmap( | 
| -      env, picture->width(), picture->height())); | 
| -  if (!jbitmap.obj()) | 
| -    return ScopedJavaLocalRef<jobject>(); | 
| - | 
| -  if (!RasterizeIntoBitmap(env, jbitmap.obj(), 0, 0, | 
| -      base::Bind(&AwContents::RenderPicture, base::Unretained(this)))) | 
| -    return ScopedJavaLocalRef<jobject>(); | 
| - | 
| -  return Java_AwContents_recordBitmapIntoPicture(env, jbitmap.obj()); | 
| -} | 
| - | 
| -bool AwContents::RenderSW(SkCanvas* canvas) { | 
| -  // TODO(leandrogracia): once Ubercompositor is ready and we support software | 
| -  // rendering mode, we should avoid this as much as we can, ideally always. | 
| -  // This includes finding a proper replacement for onDraw calls in hardware | 
| -  // mode with software canvases. http://crbug.com/170086. | 
| -  return RenderPicture(canvas); | 
| -} | 
| - | 
| -bool AwContents::RenderPicture(SkCanvas* canvas) { | 
| -  skia::RefPtr<SkPicture> picture = GetLastCapturedPicture(); | 
| -  if (!picture) | 
| -    return false; | 
| - | 
| -  // Correct device scale. | 
| -  canvas->scale(dpi_scale_, dpi_scale_); | 
| - | 
| -  picture->draw(canvas); | 
| -  return true; | 
| +  return browser_view_renderer_->CapturePicture(); | 
| } | 
|  | 
| void AwContents::EnableOnNewPicture(JNIEnv* env, | 
| jobject obj, | 
| jboolean enabled, | 
| jboolean invalidation_only) { | 
| +  BrowserViewRenderer::OnNewPictureMode mode = | 
| +      BrowserViewRenderer::kOnNewPictureDisabled; | 
| if (enabled) { | 
| -    on_new_picture_mode_ = invalidation_only ? kOnNewPictureInvalidationOnly : | 
| -        kOnNewPictureEnabled; | 
| -  } else { | 
| -    on_new_picture_mode_ = kOnNewPictureDisabled; | 
| -  } | 
| - | 
| -  // If onNewPicture is triggered only on invalidation do not capture | 
| -  // pictures on every new frame. | 
| -  if (on_new_picture_mode_ == kOnNewPictureInvalidationOnly) | 
| -    enabled = false; | 
| - | 
| -  // TODO(leandrogracia): when SW rendering uses the compositor rather than | 
| -  // picture rasterization, send update the renderer side with the correct | 
| -  // listener state. (For now, we always leave render picture listener enabled). | 
| -  // render_view_host_ext_->EnableCapturePictureCallback(enabled); | 
| -} | 
| - | 
| -void AwContents::OnPictureUpdated(int process_id, int render_view_id) { | 
| -  CHECK_EQ(web_contents_->GetRenderProcessHost()->GetID(), process_id); | 
| -  if (render_view_id != web_contents_->GetRoutingID()) | 
| -    return; | 
| - | 
| -  // TODO(leandrogracia): this can be made unconditional once software rendering | 
| -  // uses Ubercompositor. Until then this path is required for SW invalidations. | 
| -  if (on_new_picture_mode_ == kOnNewPictureEnabled) { | 
| -    JNIEnv* env = AttachCurrentThread(); | 
| -    ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); | 
| -    if (!obj.is_null()) { | 
| -      ScopedJavaLocalRef<jobject> picture = CapturePicture(env, obj.obj()); | 
| -      Java_AwContents_onNewPicture(env, obj.obj(), picture.obj()); | 
| -    } | 
| -  } | 
| - | 
| -  // TODO(leandrogracia): delete when sw rendering uses Ubercompositor. | 
| -  // Invalidation should be provided by the compositor only. | 
| -  Invalidate(); | 
| -} | 
| - | 
| -skia::RefPtr<SkPicture> AwContents::GetLastCapturedPicture() { | 
| -  // Use the latest available picture if the listener callback is enabled. | 
| -  skia::RefPtr<SkPicture> picture; | 
| -  if (on_new_picture_mode_ == kOnNewPictureEnabled) | 
| -    picture = RendererPictureMap::GetInstance()->GetRendererPicture( | 
| -        web_contents_->GetRoutingID()); | 
| - | 
| -  // If not available or not in listener mode get it synchronously. | 
| -  if (!picture) { | 
| -    render_view_host_ext_->CapturePictureSync(); | 
| -    picture = RendererPictureMap::GetInstance()->GetRendererPicture( | 
| -        web_contents_->GetRoutingID()); | 
| +    mode = invalidation_only ? | 
| +        BrowserViewRenderer::kOnNewPictureInvalidationOnly : | 
| +        BrowserViewRenderer::kOnNewPictureEnabled; | 
| } | 
|  | 
| -  return picture; | 
| +  browser_view_renderer_->EnableOnNewPicture(mode); | 
| } | 
|  | 
| }  // namespace android_webview | 
|  |