Index: android_webview/browser/in_process_view_renderer.cc |
diff --git a/android_webview/browser/in_process_view_renderer.cc b/android_webview/browser/in_process_view_renderer.cc |
index f5f134ee465d5fa4b0d3e033886c03248fe57d7f..bca50c01a73cccc4ac26ada0dd8b2eb093beb86d 100644 |
--- a/android_webview/browser/in_process_view_renderer.cc |
+++ b/android_webview/browser/in_process_view_renderer.cc |
@@ -110,6 +110,26 @@ bool RenderPictureToCanvas(SkPicture* picture, SkCanvas* canvas) { |
return true; |
} |
+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); |
@@ -413,12 +433,32 @@ bool InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded( |
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(); |
+ SkMatrix matrix; |
+ SkBitmap::Config config(SkBitmap::kNo_Config); |
+ if (pixels) { |
+ switch (pixels->config) { |
+ case AwConfig_ARGB_8888: |
+ config = SkBitmap::kARGB_8888_Config; |
+ break; |
+ case AwConfig_RGB_565: |
+ config = SkBitmap::kRGB_565_Config; |
+ break; |
+ } |
- AwDrawSWFunctionTable* sw_functions = GetAwDrawSWFunctionTable(); |
- AwPixelInfo* pixels = sw_functions ? |
- sw_functions->access_pixels(env, java_canvas) : NULL; |
- if (pixels == NULL) { |
+ for (int i = 0; i < 9; i++) { |
+ matrix.set(i, pixels->matrix[i]); |
+ } |
+ // Workaround for http://crbug.com/271096: SW draw only supports |
+ // translate & scale transforms. |
+ if (matrix.getType() & ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) |
+ config = SkBitmap::kNo_Config; |
+ } |
+ |
+ if (config == SkBitmap::kNo_Config) { |
// Render into an auxiliary bitmap if pixel info is not available. |
ScopedJavaLocalRef<jobject> jcanvas(env, java_canvas); |
TRACE_EVENT0("android_webview", "RenderToAuxBitmap"); |
@@ -447,41 +487,43 @@ bool InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded( |
} |
// 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); |
- |
- if (pixels->clip_region_size) { |
- SkRegion clip_region; |
- size_t bytes_read = clip_region.readFromMemory(pixels->clip_region); |
- DCHECK_EQ(pixels->clip_region_size, bytes_read); |
- canvas.setClipRegion(clip_region); |
- } else { |
- canvas.clipRect(gfx::RectToSkRect(clip)); |
+ SkBitmap bitmap; |
+ bitmap.setConfig(config, |
+ pixels->width, |
+ pixels->height, |
+ pixels->row_bytes); |
+ bitmap.setPixels(pixels->pixels); |
+ SkDevice device(bitmap); |
+ SkCanvas canvas(&device); |
+ canvas.setMatrix(matrix); |
+ |
+ if (pixels->clip_region) { |
+ SkRegion clip_region; |
+ size_t bytes_read = clip_region.readFromMemory(pixels->clip_region); |
+ DCHECK_EQ(pixels->clip_region_size, bytes_read); |
+ canvas.setClipRegion(clip_region); |
+ } else if (pixels->clip_rect_count) { |
+ SkRegion clip; |
+ for (int i = 0; i < pixels->clip_rect_count; ++i) { |
+ clip.op(SkIRect::MakeXYWH(pixels->clip_rects[i + 0], |
+ pixels->clip_rects[i + 1], |
+ pixels->clip_rects[i + 2], |
+ pixels->clip_rects[i + 3]), |
+ SkRegion::kUnion_Op); |
} |
- canvas.translate(scroll_correction.x(), |
- scroll_correction.y()); |
- |
- succeeded = render_source.Run(&canvas); |
+ canvas.setClipRegion(clip); |
} |
- sw_functions->release_pixels(pixels); |
- return succeeded; |
+ canvas.translate(scroll_correction.x(), |
+ scroll_correction.y()); |
+ |
+ return render_source.Run(&canvas); |
} |
skia::RefPtr<SkPicture> InProcessViewRenderer::CapturePicture(int width, |
int height) { |
+ TRACE_EVENT0("android_webview", "InProcessViewRenderer::CapturePicture"); |
+ |
// Return empty Picture objects for empty SkPictures. |
skia::RefPtr<SkPicture> picture = skia::AdoptRef(new SkPicture); |
if (width <= 0 || height <= 0) { |