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.
4
5package org.chromium.android_webview;
6
7import android.graphics.Bitmap;
8import android.graphics.Canvas;
9import android.graphics.Color;
10import android.graphics.Picture;
11import android.util.Log;
12import android.util.LruCache;
13
14import org.chromium.base.CalledByNative;
15import org.chromium.base.JNINamespace;
16import org.chromium.content.common.TraceEvent;
17
18/**
19 * Provides auxiliary methods related to Picture objects and native SkPictures.
20 */
21@JNINamespace("android_webview")
22public class JavaBrowserViewRendererHelper {
23    private static final String LOGTAG = "JavaBrowserViewRendererHelper";
24
25    // Until the full HW path is ready, we limit to 5 AwContents on the screen at once.
26    private static LruCache<Integer, Bitmap> sBitmapCache = new LruCache<Integer, Bitmap>(5);
27
28    /**
29     * Provides a Bitmap object with a given width and height used for auxiliary rasterization.
30     * |canvas| is optional and if supplied indicates the Canvas that this Bitmap will be
31     * drawn into. Note the Canvas will not be modified in any way. If |ownerKey| is non-zero
32     * the Bitmap will be cached in sBitmapCache for future use.
33     */
34    @CalledByNative
35    private static Bitmap createBitmap(int width, int height, Canvas canvas, int ownerKey) {
36        if (canvas != null) {
37            // When drawing into a Canvas, there is a maximum size imposed
38            // on Bitmaps that can be drawn. Respect that limit.
39            width = Math.min(width, canvas.getMaximumBitmapWidth());
40            height = Math.min(height, canvas.getMaximumBitmapHeight());
41        }
42        Bitmap bitmap = sBitmapCache.get(ownerKey);
43        if (bitmap == null || bitmap.getWidth() != width || bitmap.getHeight() != height) {
44            try {
45                bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
46            } catch (OutOfMemoryError e) {
47                android.util.Log.w(LOGTAG, "Error allocating bitmap");
48                return null;
49            }
50            if (ownerKey != 0) {
51                if (sBitmapCache.size() > AwContents.getNativeInstanceCount()) {
52                    sBitmapCache.evictAll();
53                }
54                sBitmapCache.put(ownerKey, bitmap);
55            }
56        }
57        return bitmap;
58    }
59
60    /**
61     * Draws a provided bitmap into a canvas.
62     * Used for convenience from the native side and other static helper methods.
63     */
64    @CalledByNative
65    private static void drawBitmapIntoCanvas(Bitmap bitmap, Canvas canvas, int x, int y) {
66        canvas.drawBitmap(bitmap, x, y, null);
67    }
68
69    /**
70     * Creates a new Picture that records drawing a provided bitmap.
71     * Will return an empty Picture if the Bitmap is null.
72     */
73    @CalledByNative
74    private static Picture recordBitmapIntoPicture(Bitmap bitmap) {
75        Picture picture = new Picture();
76        if (bitmap != null) {
77            Canvas recordingCanvas = picture.beginRecording(bitmap.getWidth(), bitmap.getHeight());
78            drawBitmapIntoCanvas(bitmap, recordingCanvas, 0, 0);
79            picture.endRecording();
80        }
81        return picture;
82    }
83
84    // Should never be instantiated.
85    private JavaBrowserViewRendererHelper() {
86    }
87}
88