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, ¤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) { |
- 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 |