diff options
author | boliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-20 19:33:57 +0000 |
---|---|---|
committer | boliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-20 19:33:57 +0000 |
commit | ad48f9ccf0d2338987adcb7e15adbf438edb8aca (patch) | |
tree | 795c38cdb294b161644b1ce171ceeacaa5226b89 /android_webview | |
parent | 8914ff4f92a1bdeed6ccfdf0bf48a6ca80d5e03f (diff) | |
download | chromium_src-ad48f9ccf0d2338987adcb7e15adbf438edb8aca.zip chromium_src-ad48f9ccf0d2338987adcb7e15adbf438edb8aca.tar.gz chromium_src-ad48f9ccf0d2338987adcb7e15adbf438edb8aca.tar.bz2 |
aw: Refactor and clean up software rendering code
Move most of logic to JavaBrowserViewRendererHelper.
Remove dead code.
Remove bitmap caching since nothing in production should be hitting
auxillary bitmap code.
BUG=
NOTRY=true
Review URL: https://codereview.chromium.org/166903008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@252351 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'android_webview')
-rw-r--r-- | android_webview/browser/browser_view_renderer.h | 31 | ||||
-rw-r--r-- | android_webview/browser/in_process_view_renderer.cc | 151 | ||||
-rw-r--r-- | android_webview/browser/in_process_view_renderer.h | 12 | ||||
-rw-r--r-- | android_webview/java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java | 44 | ||||
-rw-r--r-- | android_webview/native/aw_contents.cc | 12 | ||||
-rw-r--r-- | android_webview/native/aw_picture.cc | 16 | ||||
-rw-r--r-- | android_webview/native/java_browser_view_renderer_helper.cc | 174 | ||||
-rw-r--r-- | android_webview/native/java_browser_view_renderer_helper.h | 31 | ||||
-rw-r--r-- | android_webview/public/browser/draw_sw.h | 6 |
9 files changed, 198 insertions, 279 deletions
diff --git a/android_webview/browser/browser_view_renderer.h b/android_webview/browser/browser_view_renderer.h index 951e5cc..5b2056d 100644 --- a/android_webview/browser/browser_view_renderer.h +++ b/android_webview/browser/browser_view_renderer.h @@ -6,11 +6,13 @@ #define ANDROID_WEBVIEW_BROWSER_BROWSER_VIEW_RENDERER_H_ #include "base/android/scoped_java_ref.h" +#include "base/callback.h" #include "skia/ext/refptr.h" #include "ui/gfx/point.h" #include "ui/gfx/rect.h" #include "ui/gfx/vector2d_f.h" +class SkCanvas; class SkPicture; struct AwDrawGLInfo; struct AwDrawSWFunctionTable; @@ -73,26 +75,14 @@ class BrowserViewRenderer { // Delegate to perform rendering actions involving Java objects. class JavaHelper { public: - // Creates a RGBA_8888 Java Bitmap object of the requested size. - virtual base::android::ScopedJavaLocalRef<jobject> CreateBitmap( - JNIEnv* env, - int width, - int height, - const base::android::JavaRef<jobject>& jcanvas, - void* owner_key) = 0; - - // Draws the provided Java Bitmap into the provided Java Canvas. - virtual void DrawBitmapIntoCanvas( - JNIEnv* env, - const base::android::JavaRef<jobject>& jbitmap, - const base::android::JavaRef<jobject>& jcanvas, - int x, - int y) = 0; - - // Creates a Java Picture object that records drawing the provided Bitmap. - virtual base::android::ScopedJavaLocalRef<jobject> RecordBitmapIntoPicture( - JNIEnv* env, - const base::android::JavaRef<jobject>& jbitmap) = 0; + static JavaHelper* GetInstance(); + + typedef base::Callback<bool(SkCanvas*)> RenderMethod; + virtual bool RenderViaAuxilaryBitmapIfNeeded( + jobject java_canvas, + const gfx::Vector2d& scroll_correction, + const gfx::Rect& clip, + RenderMethod render_source) = 0; protected: virtual ~JavaHelper() {} @@ -100,7 +90,6 @@ class BrowserViewRenderer { // Global hookup methods. static void SetAwDrawSWFunctionTable(AwDrawSWFunctionTable* table); - static AwDrawSWFunctionTable* GetAwDrawSWFunctionTable(); // Rendering methods. diff --git a/android_webview/browser/in_process_view_renderer.cc b/android_webview/browser/in_process_view_renderer.cc index b0df091..48a43e1 100644 --- a/android_webview/browser/in_process_view_renderer.cc +++ b/android_webview/browser/in_process_view_renderer.cc @@ -4,13 +4,10 @@ #include "android_webview/browser/in_process_view_renderer.h" -#include <android/bitmap.h> - #include "android_webview/browser/aw_gl_surface.h" #include "android_webview/browser/scoped_app_gl_state_restore.h" #include "android_webview/common/aw_switches.h" #include "android_webview/public/browser/draw_gl.h" -#include "android_webview/public/browser/draw_sw.h" #include "base/android/jni_android.h" #include "base/auto_reset.h" #include "base/command_line.h" @@ -26,13 +23,9 @@ #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkBitmapDevice.h" #include "third_party/skia/include/core/SkCanvas.h" -#include "third_party/skia/include/core/SkGraphics.h" #include "third_party/skia/include/core/SkPicture.h" -#include "third_party/skia/include/utils/SkCanvasStateUtils.h" -#include "ui/gfx/skia_util.h" #include "ui/gfx/transform.h" #include "ui/gfx/vector2d_conversions.h" -#include "ui/gfx/vector2d_f.h" using base::android::AttachCurrentThread; using base::android::JavaRef; @@ -64,78 +57,12 @@ class UserData : public content::WebContents::Data { InProcessViewRenderer* instance_; }; -bool RasterizeIntoBitmap(JNIEnv* env, - const JavaRef<jobject>& jbitmap, - int scroll_x, - int scroll_y, - const InProcessViewRenderer::RenderMethod& renderer) { - DCHECK(jbitmap.obj()); - - AndroidBitmapInfo bitmap_info; - if (AndroidBitmap_getInfo(env, jbitmap.obj(), &bitmap_info) < 0) { - LOG(ERROR) << "Error getting java bitmap info."; - return false; - } - - void* pixels = NULL; - if (AndroidBitmap_lockPixels(env, jbitmap.obj(), &pixels) < 0) { - LOG(ERROR) << "Error locking java bitmap pixels."; - return false; - } - - bool succeeded; - { - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, - bitmap_info.width, - bitmap_info.height, - bitmap_info.stride); - bitmap.setPixels(pixels); - - SkBitmapDevice device(bitmap); - SkCanvas canvas(&device); - canvas.translate(-scroll_x, -scroll_y); - succeeded = renderer.Run(&canvas); - } - - if (AndroidBitmap_unlockPixels(env, jbitmap.obj()) < 0) { - LOG(ERROR) << "Error unlocking java bitmap pixels."; - return false; - } - - return succeeded; -} - -class ScopedPixelAccess { - public: - ScopedPixelAccess(JNIEnv* env, jobject java_canvas) { - AwDrawSWFunctionTable* sw_functions = - BrowserViewRenderer::GetAwDrawSWFunctionTable(); - pixels_ = sw_functions ? - sw_functions->access_pixels(env, java_canvas) : NULL; - } - ~ScopedPixelAccess() { - if (pixels_) - BrowserViewRenderer::GetAwDrawSWFunctionTable()->release_pixels(pixels_); - } - AwPixelInfo* pixels() { return pixels_; } - - private: - AwPixelInfo* pixels_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedPixelAccess); -}; - bool HardwareEnabled() { static bool g_hw_enabled = !CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableWebViewGLMode); return g_hw_enabled; } -// Provides software rendering functions from the Android glue layer. -// Allows preventing extra copies of data when rendering. -AwDrawSWFunctionTable* g_sw_draw_functions = NULL; - const int64 kFallbackTickTimeoutInMilliseconds = 20; // Used to calculate memory and resource allocation. Determined experimentally. @@ -273,23 +200,10 @@ base::LazyInstance<scoped_refptr<DeferredGpuCommandService> > g_service = } // namespace -// static -void BrowserViewRenderer::SetAwDrawSWFunctionTable( - AwDrawSWFunctionTable* table) { - g_sw_draw_functions = table; -} - -// static -AwDrawSWFunctionTable* BrowserViewRenderer::GetAwDrawSWFunctionTable() { - return g_sw_draw_functions; -} - InProcessViewRenderer::InProcessViewRenderer( BrowserViewRenderer::Client* client, - JavaHelper* java_helper, content::WebContents* web_contents) : client_(client), - java_helper_(java_helper), web_contents_(web_contents), compositor_(NULL), is_paused_(false), @@ -610,72 +524,11 @@ bool InProcessViewRenderer::DrawSWInternal(jobject java_canvas, return false; } - return RenderViaAuxilaryBitmapIfNeeded( + return JavaHelper::GetInstance()->RenderViaAuxilaryBitmapIfNeeded( java_canvas, - java_helper_, scroll_at_start_of_frame_, clip, - base::Bind(&InProcessViewRenderer::CompositeSW, - base::Unretained(this)), - web_contents_); -} - -// static -bool InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded( - jobject java_canvas, - BrowserViewRenderer::JavaHelper* java_helper, - const gfx::Vector2d& scroll_correction, - const gfx::Rect& clip, - InProcessViewRenderer::RenderMethod render_source, - void* owner_key) { - TRACE_EVENT0("android_webview", - "InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded"); - - JNIEnv* env = AttachCurrentThread(); - ScopedPixelAccess auto_release_pixels(env, java_canvas); - AwPixelInfo* pixels = auto_release_pixels.pixels(); - if (pixels && pixels->state) { - skia::RefPtr<SkCanvas> canvas = skia::AdoptRef( - SkCanvasStateUtils::CreateFromCanvasState(pixels->state)); - - // Workarounds for http://crbug.com/271096: SW draw only supports - // translate & scale transforms, and a simple rectangular clip. - if (canvas && (!canvas->getTotalClip().isRect() || - (canvas->getTotalMatrix().getType() & - ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)))) { - canvas.clear(); - } - if (canvas) { - canvas->translate(scroll_correction.x(), scroll_correction.y()); - return render_source.Run(canvas.get()); - } - } - - // Render into an auxiliary bitmap if pixel info is not available. - ScopedJavaLocalRef<jobject> jcanvas(env, java_canvas); - TRACE_EVENT0("android_webview", "RenderToAuxBitmap"); - ScopedJavaLocalRef<jobject> jbitmap(java_helper->CreateBitmap( - env, clip.width(), clip.height(), jcanvas, owner_key)); - if (!jbitmap.obj()) { - TRACE_EVENT_INSTANT0("android_webview", - "EarlyOut_BitmapAllocFail", - TRACE_EVENT_SCOPE_THREAD); - return false; - } - - if (!RasterizeIntoBitmap(env, jbitmap, - clip.x() - scroll_correction.x(), - clip.y() - scroll_correction.y(), - render_source)) { - TRACE_EVENT_INSTANT0("android_webview", - "EarlyOut_RasterizeFail", - TRACE_EVENT_SCOPE_THREAD); - return false; - } - - java_helper->DrawBitmapIntoCanvas(env, jbitmap, jcanvas, - clip.x(), clip.y()); - return true; + base::Bind(&InProcessViewRenderer::CompositeSW, base::Unretained(this))); } skia::RefPtr<SkPicture> InProcessViewRenderer::CapturePicture(int width, diff --git a/android_webview/browser/in_process_view_renderer.h b/android_webview/browser/in_process_view_renderer.h index a53120e..e6741b0 100644 --- a/android_webview/browser/in_process_view_renderer.h +++ b/android_webview/browser/in_process_view_renderer.h @@ -34,23 +34,12 @@ class InProcessViewRenderer : public BrowserViewRenderer, static void CalculateTileMemoryPolicy(); InProcessViewRenderer(BrowserViewRenderer::Client* client, - JavaHelper* java_helper, content::WebContents* web_contents); virtual ~InProcessViewRenderer(); static InProcessViewRenderer* FromWebContents( content::WebContents* contents); - // TODO(joth): consider extracting this to its own utility class. - typedef base::Callback<bool(SkCanvas*)> RenderMethod; - static bool RenderViaAuxilaryBitmapIfNeeded( - jobject java_canvas, - JavaHelper* java_helper, - const gfx::Vector2d& scroll_correction, - const gfx::Rect& clip, - RenderMethod render_source, - void* owner_key); - // BrowserViewRenderer overrides virtual bool OnDraw(jobject java_canvas, bool is_hardware_canvas, @@ -130,7 +119,6 @@ class InProcessViewRenderer : public BrowserViewRenderer, std::string ToString(AwDrawGLInfo* draw_info) const; BrowserViewRenderer::Client* client_; - BrowserViewRenderer::JavaHelper* java_helper_; content::WebContents* web_contents_; content::SynchronousCompositor* compositor_; diff --git a/android_webview/java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java b/android_webview/java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java index adb956f..4df7b4a 100644 --- a/android_webview/java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java +++ b/android_webview/java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java @@ -6,8 +6,6 @@ package org.chromium.android_webview; import android.graphics.Bitmap; import android.graphics.Canvas; -import android.graphics.Picture; -import android.util.LruCache; import org.chromium.base.CalledByNative; import org.chromium.base.JNINamespace; @@ -19,37 +17,24 @@ import org.chromium.base.JNINamespace; public class JavaBrowserViewRendererHelper { private static final String LOGTAG = "JavaBrowserViewRendererHelper"; - // Until the full HW path is ready, we limit to 5 AwContents on the screen at once. - private static LruCache<Long, Bitmap> sBitmapCache = new LruCache<Long, Bitmap>(5); - /** * Provides a Bitmap object with a given width and height used for auxiliary rasterization. * |canvas| is optional and if supplied indicates the Canvas that this Bitmap will be - * drawn into. Note the Canvas will not be modified in any way. If |ownerKey| is non-zero - * the Bitmap will be cached in sBitmapCache for future use. + * drawn into. Note the Canvas will not be modified in any way. */ @CalledByNative - private static Bitmap createBitmap(int width, int height, Canvas canvas, long ownerKey) { + private static Bitmap createBitmap(int width, int height, Canvas canvas) { if (canvas != null) { // When drawing into a Canvas, there is a maximum size imposed // on Bitmaps that can be drawn. Respect that limit. width = Math.min(width, canvas.getMaximumBitmapWidth()); height = Math.min(height, canvas.getMaximumBitmapHeight()); } - Bitmap bitmap = sBitmapCache.get(ownerKey); - if (bitmap == null || bitmap.getWidth() != width || bitmap.getHeight() != height) { - try { - bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); - } catch (OutOfMemoryError e) { - android.util.Log.w(LOGTAG, "Error allocating bitmap"); - return null; - } - if (ownerKey != 0) { - if (sBitmapCache.size() > AwContents.getNativeInstanceCount()) { - sBitmapCache.evictAll(); - } - sBitmapCache.put(ownerKey, bitmap); - } + Bitmap bitmap = null; + try { + bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + } catch (OutOfMemoryError e) { + android.util.Log.w(LOGTAG, "Error allocating bitmap"); } return bitmap; } @@ -63,21 +48,6 @@ public class JavaBrowserViewRendererHelper { canvas.drawBitmap(bitmap, x, y, null); } - /** - * Creates a new Picture that records drawing a provided bitmap. - * Will return an empty Picture if the Bitmap is null. - */ - @CalledByNative - private static Picture recordBitmapIntoPicture(Bitmap bitmap) { - Picture picture = new Picture(); - if (bitmap != null) { - Canvas recordingCanvas = picture.beginRecording(bitmap.getWidth(), bitmap.getHeight()); - drawBitmapIntoCanvas(bitmap, recordingCanvas, 0, 0); - picture.endRecording(); - } - return picture; - } - // Should never be instantiated. private JavaBrowserViewRendererHelper() { } diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc index 5e73ed0..7c8d35c 100644 --- a/android_webview/native/aw_contents.cc +++ b/android_webview/native/aw_contents.cc @@ -96,10 +96,6 @@ namespace { bool g_should_download_favicons = false; -JavaBrowserViewRendererHelper* java_renderer_helper() { - return JavaBrowserViewRendererHelper::GetInstance(); -} - const void* kAwContentsUserDataKey = &kAwContentsUserDataKey; class AwContentsUserData : public base::SupportsUserData::Data { @@ -188,9 +184,9 @@ AwContents* AwContents::FromID(int render_process_id, int render_view_id) { AwContents::AwContents(scoped_ptr<WebContents> web_contents) : web_contents_(web_contents.Pass()), - browser_view_renderer_( - new InProcessViewRenderer(this, java_renderer_helper(), - web_contents_.get())) { + browser_view_renderer_(new InProcessViewRenderer( + this, + web_contents_.get())) { base::subtle::NoBarrier_AtomicIncrement(&g_instance_count, 1); icon_helper_.reset(new IconHelper(web_contents_.get())); icon_helper_->SetListener(this); @@ -342,7 +338,7 @@ static jlong Init(JNIEnv* env, jclass, jobject browser_context) { } static void SetAwDrawSWFunctionTable(JNIEnv* env, jclass, jint function_table) { - BrowserViewRenderer::SetAwDrawSWFunctionTable( + JavaBrowserViewRendererHelper::SetAwDrawSWFunctionTable( reinterpret_cast<AwDrawSWFunctionTable*>(function_table)); } diff --git a/android_webview/native/aw_picture.cc b/android_webview/native/aw_picture.cc index bc02b5b..9a7ff83 100644 --- a/android_webview/native/aw_picture.cc +++ b/android_webview/native/aw_picture.cc @@ -4,8 +4,8 @@ #include "android_webview/native/aw_picture.h" -#include "android_webview/browser/in_process_view_renderer.h" #include "android_webview/native/java_browser_view_renderer_helper.h" +#include "base/bind.h" #include "jni/AwPicture_jni.h" #include "third_party/skia/include/core/SkPicture.h" @@ -39,13 +39,13 @@ bool RenderPictureToCanvas(SkPicture* picture, SkCanvas* canvas) { void AwPicture::Draw(JNIEnv* env, jobject obj, jobject canvas, jint left, jint top, jint right, jint bottom) { - bool ok = InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded( - canvas, - JavaBrowserViewRendererHelper::GetInstance(), - gfx::Vector2d(), - gfx::Rect(left, top, right - left, bottom - top), - base::Bind(&RenderPictureToCanvas, base::Unretained(picture_.get())), - this); + bool ok = JavaBrowserViewRendererHelper::GetInstance() + ->RenderViaAuxilaryBitmapIfNeeded( + canvas, + gfx::Vector2d(), + gfx::Rect(left, top, right - left, bottom - top), + base::Bind(&RenderPictureToCanvas, + base::Unretained(picture_.get()))); LOG_IF(ERROR, !ok) << "Couldn't draw picture"; } diff --git a/android_webview/native/java_browser_view_renderer_helper.cc b/android_webview/native/java_browser_view_renderer_helper.cc index 1066d71..de0a0fe 100644 --- a/android_webview/native/java_browser_view_renderer_helper.cc +++ b/android_webview/native/java_browser_view_renderer_helper.cc @@ -4,18 +4,52 @@ #include "android_webview/native/java_browser_view_renderer_helper.h" +#include <android/bitmap.h> + +#include "android_webview/public/browser/draw_sw.h" #include "base/debug/trace_event.h" #include "jni/JavaBrowserViewRendererHelper_jni.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "third_party/skia/include/core/SkBitmapDevice.h" +#include "third_party/skia/include/utils/SkCanvasStateUtils.h" using base::android::JavaRef; using base::android::ScopedJavaLocalRef; namespace android_webview { -JavaBrowserViewRendererHelper::JavaBrowserViewRendererHelper() { -} +namespace { + +// Provides software rendering functions from the Android glue layer. +// Allows preventing extra copies of data when rendering. +AwDrawSWFunctionTable* g_sw_draw_functions = NULL; + +class ScopedPixelAccess { + public: + ScopedPixelAccess(JNIEnv* env, jobject java_canvas) : pixels_(NULL) { + if (g_sw_draw_functions) + pixels_ = g_sw_draw_functions->access_pixels(env, java_canvas); + } + + ~ScopedPixelAccess() { + if (pixels_) + g_sw_draw_functions->release_pixels(pixels_); + } + + AwPixelInfo* pixels() { return pixels_; } + + private: + AwPixelInfo* pixels_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedPixelAccess); +}; + +} // namespace -JavaBrowserViewRendererHelper::~JavaBrowserViewRendererHelper() { +// static +void JavaBrowserViewRendererHelper::SetAwDrawSWFunctionTable( + AwDrawSWFunctionTable* table) { + g_sw_draw_functions = table; } // static @@ -25,41 +59,123 @@ JavaBrowserViewRendererHelper* JavaBrowserViewRendererHelper::GetInstance() { return g_instance; } -ScopedJavaLocalRef<jobject> JavaBrowserViewRendererHelper::CreateBitmap( - JNIEnv* env, - int width, - int height, - const base::android::JavaRef<jobject>& jcanvas, - void* owner_key) { - TRACE_EVENT0("android_webview", "RendererHelper::CreateBitmap"); - return width <= 0 || height <= 0 ? ScopedJavaLocalRef<jobject>() : - Java_JavaBrowserViewRendererHelper_createBitmap( - env, width, height, jcanvas.obj(), - reinterpret_cast<intptr_t>(owner_key)); +// static +BrowserViewRenderer::JavaHelper* +BrowserViewRenderer::JavaHelper::GetInstance() { + return JavaBrowserViewRendererHelper::GetInstance(); } -void JavaBrowserViewRendererHelper::DrawBitmapIntoCanvas( - JNIEnv* env, - const JavaRef<jobject>& jbitmap, - const JavaRef<jobject>& jcanvas, - int x, - int y) { - TRACE_EVENT0("android_webview", "RendererHelper::DrawBitmapIntoCanvas"); - Java_JavaBrowserViewRendererHelper_drawBitmapIntoCanvas( - env, jbitmap.obj(), jcanvas.obj(), x, y); +JavaBrowserViewRendererHelper::JavaBrowserViewRendererHelper() {} + +JavaBrowserViewRendererHelper::~JavaBrowserViewRendererHelper() {} + +bool JavaBrowserViewRendererHelper::RenderViaAuxilaryBitmapIfNeeded( + jobject java_canvas, + const gfx::Vector2d& scroll_correction, + const gfx::Rect& clip, + RenderMethod render_source) { + TRACE_EVENT0("android_webview", "RenderViaAuxilaryBitmapIfNeeded"); + + JNIEnv* env = base::android::AttachCurrentThread(); + ScopedPixelAccess auto_release_pixels(env, java_canvas); + AwPixelInfo* pixels = auto_release_pixels.pixels(); + if (pixels && pixels->state) { + skia::RefPtr<SkCanvas> canvas = skia::AdoptRef( + SkCanvasStateUtils::CreateFromCanvasState(pixels->state)); + + // Workarounds for http://crbug.com/271096: SW draw only supports + // translate & scale transforms, and a simple rectangular clip. + if (canvas && (!canvas->getTotalClip().isRect() || + (canvas->getTotalMatrix().getType() & + ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)))) { + canvas.clear(); + } + if (canvas) { + canvas->translate(scroll_correction.x(), scroll_correction.y()); + return render_source.Run(canvas.get()); + } + } + return RenderViaAuxilaryBitmap( + env, java_canvas, scroll_correction, clip, render_source); } -ScopedJavaLocalRef<jobject> -JavaBrowserViewRendererHelper::RecordBitmapIntoPicture( +bool JavaBrowserViewRendererHelper::RenderViaAuxilaryBitmap( JNIEnv* env, - const JavaRef<jobject>& jbitmap) { - TRACE_EVENT0("android_webview", "RendererHelper::RecordBitmapIntoPicture"); - return Java_JavaBrowserViewRendererHelper_recordBitmapIntoPicture( - env, jbitmap.obj()); + jobject java_canvas, + const gfx::Vector2d& scroll_correction, + const gfx::Rect& clip, + const RenderMethod& render_source) { + // Render into an auxiliary bitmap if pixel info is not available. + ScopedJavaLocalRef<jobject> jcanvas(env, java_canvas); + TRACE_EVENT0("android_webview", "RenderToAuxBitmap"); + + if (clip.width() <= 0 || clip.height() <= 0) + return false; + + ScopedJavaLocalRef<jobject> jbitmap( + Java_JavaBrowserViewRendererHelper_createBitmap( + env, clip.width(), clip.height(), jcanvas.obj())); + if (!jbitmap.obj()) + return false; + + if (!RasterizeIntoBitmap(env, + jbitmap, + clip.x() - scroll_correction.x(), + clip.y() - scroll_correction.y(), + render_source)) { + return false; + } + + Java_JavaBrowserViewRendererHelper_drawBitmapIntoCanvas( + env, jbitmap.obj(), jcanvas.obj(), clip.x(), clip.y()); + return true; } bool RegisterJavaBrowserViewRendererHelper(JNIEnv* env) { return RegisterNativesImpl(env) >= 0; } +bool JavaBrowserViewRendererHelper::RasterizeIntoBitmap( + JNIEnv* env, + const JavaRef<jobject>& jbitmap, + int scroll_x, + int scroll_y, + const JavaBrowserViewRendererHelper::RenderMethod& renderer) { + DCHECK(jbitmap.obj()); + + AndroidBitmapInfo bitmap_info; + if (AndroidBitmap_getInfo(env, jbitmap.obj(), &bitmap_info) < 0) { + LOG(ERROR) << "Error getting java bitmap info."; + return false; + } + + void* pixels = NULL; + if (AndroidBitmap_lockPixels(env, jbitmap.obj(), &pixels) < 0) { + LOG(ERROR) << "Error locking java bitmap pixels."; + return false; + } + + bool succeeded; + { + SkBitmap bitmap; + bitmap.setConfig(SkBitmap::kARGB_8888_Config, + bitmap_info.width, + bitmap_info.height, + bitmap_info.stride); + bitmap.setPixels(pixels); + + SkBitmapDevice device(bitmap); + SkCanvas canvas(&device); + canvas.translate(-scroll_x, -scroll_y); + succeeded = renderer.Run(&canvas); + } + + if (AndroidBitmap_unlockPixels(env, jbitmap.obj()) < 0) { + LOG(ERROR) << "Error unlocking java bitmap pixels."; + return false; + } + + return succeeded; +} + } // namespace android_webview diff --git a/android_webview/native/java_browser_view_renderer_helper.h b/android_webview/native/java_browser_view_renderer_helper.h index 986d737..b38ba0f 100644 --- a/android_webview/native/java_browser_view_renderer_helper.h +++ b/android_webview/native/java_browser_view_renderer_helper.h @@ -13,29 +13,34 @@ namespace android_webview { // Native side of java-class of same name. // Provides utility methods for rendering involving with Java objects. +// TODO(boliu): Rename this class to JavaRasterHelper. class JavaBrowserViewRendererHelper : public BrowserViewRenderer::JavaHelper { public: JavaBrowserViewRendererHelper(); virtual ~JavaBrowserViewRendererHelper(); + static void SetAwDrawSWFunctionTable(AwDrawSWFunctionTable* table); static JavaBrowserViewRendererHelper* GetInstance(); // BrowserViewRenderer::JavaHelper implementation. - virtual base::android::ScopedJavaLocalRef<jobject> CreateBitmap( - JNIEnv* env, - int width, - int height, - const base::android::JavaRef<jobject>& jcanvas, - void* owner_key) OVERRIDE; - virtual void DrawBitmapIntoCanvas( + virtual bool RenderViaAuxilaryBitmapIfNeeded( + jobject java_canvas, + const gfx::Vector2d& scroll_correction, + const gfx::Rect& clip, + RenderMethod render_source) OVERRIDE; + + private: + bool RenderViaAuxilaryBitmap(JNIEnv* env, + jobject java_canvas, + const gfx::Vector2d& scroll_correction, + const gfx::Rect& clip, + const RenderMethod& render_source); + bool RasterizeIntoBitmap( JNIEnv* env, const base::android::JavaRef<jobject>& jbitmap, - const base::android::JavaRef<jobject>& jcanvas, - int x, - int y) OVERRIDE; - virtual base::android::ScopedJavaLocalRef<jobject> RecordBitmapIntoPicture( - JNIEnv* env, - const base::android::JavaRef<jobject>& jbitmap) OVERRIDE; + int scroll_x, + int scroll_y, + const JavaBrowserViewRendererHelper::RenderMethod& renderer); }; bool RegisterJavaBrowserViewRendererHelper(JNIEnv* env); diff --git a/android_webview/public/browser/draw_sw.h b/android_webview/public/browser/draw_sw.h index 3f14798..91becfc 100644 --- a/android_webview/public/browser/draw_sw.h +++ b/android_webview/public/browser/draw_sw.h @@ -48,8 +48,10 @@ typedef bool (AwIsSkiaVersionCompatibleFunction)(SkiaVersionFunction function); struct AwDrawSWFunctionTable { AwAccessPixelsFunction* access_pixels; AwReleasePixelsFunction* release_pixels; - AwCreatePictureFunction* create_picture; - AwIsSkiaVersionCompatibleFunction* is_skia_version_compatible; + + // Deprecated. Remove them. + AwCreatePictureFunction* deprecated_create_picture; + AwIsSkiaVersionCompatibleFunction* deprecated_is_skia_version_compatible; }; #endif // ANDROID_WEBVIEW_PUBLIC_BROWSER_DRAW_SW_H_ |