Chromium Code Reviews| 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..aff97a507930501ab8c5f8925ddc9b51a4655614 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) { |
|
boliu
2013/08/10 01:41:40
can this be the else block to "if (pixels)" on lin
joth
2013/08/10 01:45:48
no - line 445, 448 and 458 all assign to |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,42 @@ 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_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); |
| + } else if (pixels->clip_region && 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); |
| } |
| + canvas.translate(scroll_correction.x(), |
| + scroll_correction.y()); |
| - sw_functions->release_pixels(pixels); |
| - return succeeded; |
| + 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) { |