Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2194)

Unified Diff: android_webview/native/aw_contents.cc

Issue 12041009: [Android WebView] Migrate the rendering code to a separate set of classes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: android_webview/native/aw_contents.cc
diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc
index a44fb06c5c6945cbc8b05ac3e8faea6b47783fce..2f071eb387059a7d8f7e4ac18ca96083123f21bb 100644
--- a/android_webview/native/aw_contents.cc
+++ b/android_webview/native/aw_contents.cc
@@ -4,29 +4,26 @@
#include "android_webview/native/aw_contents.h"
-#include <sys/system_properties.h>
-
#include "android_webview/browser/aw_browser_main_parts.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/browser/view_renderer_impl.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/render_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/supports_user_data.h"
-#include "cc/layer.h"
#include "content/components/navigation_interception/intercept_navigation_delegate.h"
#include "content/public/browser/android/content_view_core.h"
#include "content/public/browser/browser_thread.h"
@@ -37,24 +34,6 @@
#include "content/public/common/ssl_status.h"
#include "jni/AwContents_jni.h"
#include "net/base/x509_certificate.h"
-#include "skia/ext/refptr.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/SkPicture.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
using base::android::AttachCurrentThread;
using base::android::ConvertJavaStringToUTF16;
@@ -76,7 +55,7 @@ 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::ViewRenderer*>(view_context)->DrawGL(
draw_info);
}
}
@@ -85,7 +64,7 @@ namespace android_webview {
namespace {
-AwDrawSWFunctionTable* g_draw_sw_functions = NULL;
+static RenderHelper render_helper;
const void* kAwContentsUserDataKey = &kAwContentsUserDataKey;
@@ -118,11 +97,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),
- last_frame_context_(NULL) {
- RendererPictureMap::CreateInstance();
+ ALLOW_THIS_IN_INITIALIZER_LIST(
+ view_renderer_(ViewRendererImpl::Create(this, &render_helper))) {
android_webview::AwBrowserDependencyFactory* dependency_factory =
android_webview::AwBrowserDependencyFactory::GetInstance();
@@ -132,21 +108,12 @@ 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);
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) {
@@ -160,268 +127,6 @@ AwContents::~AwContents() {
find_helper_->SetListener(NULL);
}
-void AwContents::DrawGL(AwDrawGLInfo* draw_info) {
-
- TRACE_EVENT0("AwContents", "AwContents::DrawGL");
-
- if (!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, &current_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) {
- skia::RefPtr<SkPicture> picture =
- RendererPictureMap::GetInstance()->GetRendererPicture(
- web_contents_->GetRoutingID());
- if (!picture)
- return false;
-
- AwPixelInfo* pixels;
- if (!g_draw_sw_functions ||
- (pixels = g_draw_sw_functions->access_pixels(env, java_canvas)) == NULL) {
- // TODO(joth): Fall back to slow path rendering via temporary bitmap.
- return 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));
- }
-
- picture->draw(&canvas);
- }
-
- g_draw_sw_functions->release_pixels(pixels);
- return true;
-}
-
jint AwContents::GetWebContents(JNIEnv* env, jobject obj) {
return reinterpret_cast<jint>(web_contents_.get());
}
@@ -430,28 +135,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()));
-
- // 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();
+ view_renderer_->SetContents(core);
}
void AwContents::Destroy(JNIEnv* env, jobject obj) {
@@ -460,8 +144,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);
+ ViewRenderer::SetAwDrawSWFunctionTable(
+ reinterpret_cast<AwDrawSWFunctionTable*>(function_table));
}
// static
@@ -469,6 +153,10 @@ jint GetAwDrawGLFunction(JNIEnv* env, jclass) {
return reinterpret_cast<jint>(&DrawGLFunction);
}
+jint AwContents::GetAwDrawGLViewContext(JNIEnv* env, jobject obj) {
+ return reinterpret_cast<jint>(view_renderer_.get());
+}
+
namespace {
// |message| is passed as base::Owned, so it will automatically be deleted
// when the callback goes out of scope.
@@ -680,33 +368,18 @@ void AwContents::OnFindResultReceived(int active_ordinal,
env, obj.obj(), active_ordinal, match_count, finished);
}
-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;
-
- Java_AwContents_invalidate(env, obj.obj());
-}
-
-void AwContents::SetCompositorVisibility(bool visible) {
- if (compositor_visible_ != visible) {
- compositor_visible_ = visible;
- compositor_->SetVisible(compositor_visible_);
- }
+ if (!obj.is_null())
+ Java_AwContents_invalidate(env, obj.obj());
}
-void AwContents::OnSwapBuffersCompleted() {
+void AwContents::OnNewPicture(ScopedJavaLocalRef<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>
@@ -770,27 +443,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_);
+ 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();
+ 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_);
+ view_renderer_->OnAttachedToWindow(w, h);
}
void AwContents::OnDetachedFromWindow(JNIEnv* env, jobject obj) {
- view_visible_ = false;
- SetCompositorVisibility(false);
+ view_renderer_->OnDetachedFromWindow();
}
base::android::ScopedJavaLocalRef<jbyteArray>
@@ -823,9 +490,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 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);
+ view_renderer_->SetScrollForHWFrame(scroll_x, scroll_y);
}
void AwContents::SetPendingWebContentsForPopup(
@@ -848,14 +526,19 @@ jint AwContents::ReleasePopupWebContents(JNIEnv* env, jobject obj) {
return reinterpret_cast<jint>(pending_contents_.release());
}
-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;
+ScopedJavaLocalRef<jobject> AwContents::CapturePicture(JNIEnv* env,
+ jobject obj) {
+ return view_renderer_->CapturePicture();
+}
- // TODO(leandrogracia): delete when sw rendering uses Ubercompositor.
- // Invalidation should be provided by the compositor only.
- Invalidate();
+void AwContents::EnableOnNewPicture(JNIEnv* env,
+ jobject obj,
+ jboolean enabled,
+ jboolean invalidation_only) {
+ view_renderer_->EnableOnNewPicture(
joth 2013/01/21 22:54:24 Mode m = ViewRenderer::kOnNewPictureDisabled; if (
Leandro GraciĆ” Gil 2013/01/22 08:18:46 Done.
+ !enabled ? ViewRenderer::kOnNewPictureDisabled :
+ (invalidation_only ? ViewRenderer::kOnNewPictureInvalidationOnly :
+ ViewRenderer::kOnNewPictureEnabled));
}
} // namespace android_webview

Powered by Google App Engine
This is Rietveld 408576698