Move render_view_context_menu.* and related files out of tab_contents.
[chromium-blink-merge.git] / android_webview / native / java_browser_view_renderer_helper.cc
blobb6dd73caf2b2029cffa02b786ce74892286ae047
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "android_webview/native/java_browser_view_renderer_helper.h"
7 #include <android/bitmap.h>
9 #include "android_webview/public/browser/draw_sw.h"
10 #include "base/debug/trace_event.h"
11 #include "jni/JavaBrowserViewRendererHelper_jni.h"
12 #include "third_party/skia/include/core/SkBitmap.h"
13 #include "third_party/skia/include/core/SkBitmapDevice.h"
14 #include "third_party/skia/include/utils/SkCanvasStateUtils.h"
16 using base::android::JavaRef;
17 using base::android::ScopedJavaLocalRef;
19 namespace android_webview {
21 namespace {
23 // Provides software rendering functions from the Android glue layer.
24 // Allows preventing extra copies of data when rendering.
25 AwDrawSWFunctionTable* g_sw_draw_functions = NULL;
27 class ScopedPixelAccess {
28 public:
29 ScopedPixelAccess(JNIEnv* env, jobject java_canvas) : pixels_(NULL) {
30 if (g_sw_draw_functions)
31 pixels_ = g_sw_draw_functions->access_pixels(env, java_canvas);
34 ~ScopedPixelAccess() {
35 if (pixels_)
36 g_sw_draw_functions->release_pixels(pixels_);
39 AwPixelInfo* pixels() { return pixels_; }
41 private:
42 AwPixelInfo* pixels_;
44 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedPixelAccess);
47 } // namespace
49 // static
50 void JavaBrowserViewRendererHelper::SetAwDrawSWFunctionTable(
51 AwDrawSWFunctionTable* table) {
52 g_sw_draw_functions = table;
55 // static
56 JavaBrowserViewRendererHelper* JavaBrowserViewRendererHelper::GetInstance() {
57 static JavaBrowserViewRendererHelper* g_instance =
58 new JavaBrowserViewRendererHelper;
59 return g_instance;
62 // static
63 BrowserViewRendererJavaHelper* BrowserViewRendererJavaHelper::GetInstance() {
64 return JavaBrowserViewRendererHelper::GetInstance();
67 JavaBrowserViewRendererHelper::JavaBrowserViewRendererHelper() {}
69 JavaBrowserViewRendererHelper::~JavaBrowserViewRendererHelper() {}
71 bool JavaBrowserViewRendererHelper::RenderViaAuxilaryBitmapIfNeeded(
72 jobject java_canvas,
73 const gfx::Vector2d& scroll_correction,
74 const gfx::Rect& clip,
75 RenderMethod render_source) {
76 TRACE_EVENT0("android_webview", "RenderViaAuxilaryBitmapIfNeeded");
78 JNIEnv* env = base::android::AttachCurrentThread();
79 ScopedPixelAccess auto_release_pixels(env, java_canvas);
80 AwPixelInfo* pixels = auto_release_pixels.pixels();
81 if (pixels && pixels->state) {
82 skia::RefPtr<SkCanvas> canvas = skia::AdoptRef(
83 SkCanvasStateUtils::CreateFromCanvasState(pixels->state));
85 // Workarounds for http://crbug.com/271096: SW draw only supports
86 // translate & scale transforms, and a simple rectangular clip.
87 if (canvas && (!canvas->getTotalClip().isRect() ||
88 (canvas->getTotalMatrix().getType() &
89 ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)))) {
90 canvas.clear();
92 if (canvas) {
93 canvas->translate(scroll_correction.x(), scroll_correction.y());
94 return render_source.Run(canvas.get());
97 return RenderViaAuxilaryBitmap(
98 env, java_canvas, scroll_correction, clip, render_source);
101 bool JavaBrowserViewRendererHelper::RenderViaAuxilaryBitmap(
102 JNIEnv* env,
103 jobject java_canvas,
104 const gfx::Vector2d& scroll_correction,
105 const gfx::Rect& clip,
106 const RenderMethod& render_source) {
107 // Render into an auxiliary bitmap if pixel info is not available.
108 ScopedJavaLocalRef<jobject> jcanvas(env, java_canvas);
109 TRACE_EVENT0("android_webview", "RenderToAuxBitmap");
111 if (clip.width() <= 0 || clip.height() <= 0)
112 return false;
114 ScopedJavaLocalRef<jobject> jbitmap(
115 Java_JavaBrowserViewRendererHelper_createBitmap(
116 env, clip.width(), clip.height(), jcanvas.obj()));
117 if (!jbitmap.obj())
118 return false;
120 if (!RasterizeIntoBitmap(env,
121 jbitmap,
122 clip.x() - scroll_correction.x(),
123 clip.y() - scroll_correction.y(),
124 render_source)) {
125 return false;
128 Java_JavaBrowserViewRendererHelper_drawBitmapIntoCanvas(
129 env, jbitmap.obj(), jcanvas.obj(), clip.x(), clip.y());
130 return true;
133 bool RegisterJavaBrowserViewRendererHelper(JNIEnv* env) {
134 return RegisterNativesImpl(env) >= 0;
137 bool JavaBrowserViewRendererHelper::RasterizeIntoBitmap(
138 JNIEnv* env,
139 const JavaRef<jobject>& jbitmap,
140 int scroll_x,
141 int scroll_y,
142 const JavaBrowserViewRendererHelper::RenderMethod& renderer) {
143 DCHECK(jbitmap.obj());
145 AndroidBitmapInfo bitmap_info;
146 if (AndroidBitmap_getInfo(env, jbitmap.obj(), &bitmap_info) < 0) {
147 LOG(ERROR) << "Error getting java bitmap info.";
148 return false;
151 void* pixels = NULL;
152 if (AndroidBitmap_lockPixels(env, jbitmap.obj(), &pixels) < 0) {
153 LOG(ERROR) << "Error locking java bitmap pixels.";
154 return false;
157 bool succeeded;
159 SkBitmap bitmap;
160 bitmap.setConfig(SkBitmap::kARGB_8888_Config,
161 bitmap_info.width,
162 bitmap_info.height,
163 bitmap_info.stride);
164 bitmap.setPixels(pixels);
166 SkBitmapDevice device(bitmap);
167 SkCanvas canvas(&device);
168 canvas.translate(-scroll_x, -scroll_y);
169 succeeded = renderer.Run(&canvas);
172 if (AndroidBitmap_unlockPixels(env, jbitmap.obj()) < 0) {
173 LOG(ERROR) << "Error unlocking java bitmap pixels.";
174 return false;
177 return succeeded;
180 } // namespace android_webview