DisplayListCanvas.java revision 3d8298e1a8b35dadb0a383aadb9a545ecab463e2
1e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy/*
2e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * Copyright (C) 2010 The Android Open Source Project
3e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy *
4e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
5e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * you may not use this file except in compliance with the License.
6e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * You may obtain a copy of the License at
7e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy *
8e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
9e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy *
10e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * Unless required by applicable law or agreed to in writing, software
11e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
12e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * See the License for the specific language governing permissions and
14e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * limitations under the License.
15e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy */
16e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
17e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guypackage android.view;
18e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
19c9070ebd13263a341511cf779087a46750021196Chris Craikimport android.annotation.NonNull;
204afbed15f3b4f88c0190bbb89deba7a6ceae2da7John Reckimport android.annotation.Nullable;
21e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.Bitmap;
22f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craikimport android.graphics.Canvas;
2352244fff29042926e21fa897ef5ab11148e35299John Reckimport android.graphics.CanvasProperty;
24e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.Paint;
25c9070ebd13263a341511cf779087a46750021196Chris Craikimport android.util.Pools.SynchronizedPool;
26e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
27e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy/**
28c9070ebd13263a341511cf779087a46750021196Chris Craik * An implementation of a GL canvas that records drawing operations.
29c9070ebd13263a341511cf779087a46750021196Chris Craik * This is intended for use with a DisplayList. This class keeps a list of all the Paint and
30c9070ebd13263a341511cf779087a46750021196Chris Craik * Bitmap objects that it draws, preventing the backing memory of Bitmaps from being freed while
31c9070ebd13263a341511cf779087a46750021196Chris Craik * the DisplayList is still holding a native reference to the memory.
32f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik *
33f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik * @hide
34e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy */
35f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craikpublic class DisplayListCanvas extends Canvas {
36c9070ebd13263a341511cf779087a46750021196Chris Craik    // The recording canvas pool should be large enough to handle a deeply nested
37c9070ebd13263a341511cf779087a46750021196Chris Craik    // view hierarchy because display lists are generated recursively.
38c9070ebd13263a341511cf779087a46750021196Chris Craik    private static final int POOL_LIMIT = 25;
39c9070ebd13263a341511cf779087a46750021196Chris Craik
403d8298e1a8b35dadb0a383aadb9a545ecab463e2sergeyv    private static final int MAX_BITMAP_SIZE = 100 * 1024 * 1024; // 100 MB
413d8298e1a8b35dadb0a383aadb9a545ecab463e2sergeyv
42c9070ebd13263a341511cf779087a46750021196Chris Craik    private static final SynchronizedPool<DisplayListCanvas> sPool =
43c9070ebd13263a341511cf779087a46750021196Chris Craik            new SynchronizedPool<DisplayListCanvas>(POOL_LIMIT);
44c9070ebd13263a341511cf779087a46750021196Chris Craik
45c9070ebd13263a341511cf779087a46750021196Chris Craik    RenderNode mNode;
46e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    private int mWidth;
47e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    private int mHeight;
48051910b9f998030dacb8a0722588cc715813fde1Raph Levien
49cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger    static DisplayListCanvas obtain(@NonNull RenderNode node, int width, int height) {
50c9070ebd13263a341511cf779087a46750021196Chris Craik        if (node == null) throw new IllegalArgumentException("node cannot be null");
51c9070ebd13263a341511cf779087a46750021196Chris Craik        DisplayListCanvas canvas = sPool.acquire();
52c9070ebd13263a341511cf779087a46750021196Chris Craik        if (canvas == null) {
53cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger            canvas = new DisplayListCanvas(width, height);
54cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger        } else {
55cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger            nResetDisplayListCanvas(canvas.mNativeCanvasWrapper, width, height);
56c9070ebd13263a341511cf779087a46750021196Chris Craik        }
57c9070ebd13263a341511cf779087a46750021196Chris Craik        canvas.mNode = node;
58cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger        canvas.mWidth = width;
59cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger        canvas.mHeight = height;
60c9070ebd13263a341511cf779087a46750021196Chris Craik        return canvas;
61c9070ebd13263a341511cf779087a46750021196Chris Craik    }
62c9070ebd13263a341511cf779087a46750021196Chris Craik
63c9070ebd13263a341511cf779087a46750021196Chris Craik    void recycle() {
64c9070ebd13263a341511cf779087a46750021196Chris Craik        mNode = null;
65c9070ebd13263a341511cf779087a46750021196Chris Craik        sPool.release(this);
66c9070ebd13263a341511cf779087a46750021196Chris Craik    }
67c9070ebd13263a341511cf779087a46750021196Chris Craik
68c9070ebd13263a341511cf779087a46750021196Chris Craik    long finishRecording() {
69c9070ebd13263a341511cf779087a46750021196Chris Craik        return nFinishRecording(mNativeCanvasWrapper);
70c9070ebd13263a341511cf779087a46750021196Chris Craik    }
71c9070ebd13263a341511cf779087a46750021196Chris Craik
72c9070ebd13263a341511cf779087a46750021196Chris Craik    @Override
73c9070ebd13263a341511cf779087a46750021196Chris Craik    public boolean isRecordingFor(Object o) {
74c9070ebd13263a341511cf779087a46750021196Chris Craik        return o == mNode;
75c9070ebd13263a341511cf779087a46750021196Chris Craik    }
766926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy
77163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    ///////////////////////////////////////////////////////////////////////////
78163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    // JNI
79163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    ///////////////////////////////////////////////////////////////////////////
80163935113919a184122b8b3bd672ef08c8df65dcRomain Guy
81163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    private static native boolean nIsAvailable();
82163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    private static boolean sIsAvailable = nIsAvailable();
83163935113919a184122b8b3bd672ef08c8df65dcRomain Guy
84163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    static boolean isAvailable() {
85163935113919a184122b8b3bd672ef08c8df65dcRomain Guy        return sIsAvailable;
86163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    }
87e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
88e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
89e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // Constructors
90e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
91b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
92cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger    private DisplayListCanvas(int width, int height) {
93cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger        super(nCreateDisplayListCanvas(width, height));
949c08ee0f6cbfce4696acb166fcfbf424d8efcb31Chris Craik        mDensity = 0; // disable bitmap density scaling
95e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
96b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
97cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger    private static native long nCreateDisplayListCanvas(int width, int height);
98cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger    private static native void nResetDisplayListCanvas(long canvas, int width, int height);
99ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
100e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
101e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // Canvas management
102e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
103e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
1049c08ee0f6cbfce4696acb166fcfbf424d8efcb31Chris Craik
1059c08ee0f6cbfce4696acb166fcfbf424d8efcb31Chris Craik    @Override
1069c08ee0f6cbfce4696acb166fcfbf424d8efcb31Chris Craik    public void setDensity(int density) {
1079c08ee0f6cbfce4696acb166fcfbf424d8efcb31Chris Craik        // drop silently, since DisplayListCanvas doesn't perform density scaling
1089c08ee0f6cbfce4696acb166fcfbf424d8efcb31Chris Craik    }
1099c08ee0f6cbfce4696acb166fcfbf424d8efcb31Chris Craik
110e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
111f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    public boolean isHardwareAccelerated() {
112f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik        return true;
113f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    }
114f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik
115f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    @Override
116f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    public void setBitmap(Bitmap bitmap) {
117f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik        throw new UnsupportedOperationException();
118f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    }
119f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik
120f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    @Override
121e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public boolean isOpaque() {
1228dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        return false;
123e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
124e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
125e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
126e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public int getWidth() {
127e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        return mWidth;
128e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
129e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
130e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
131e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public int getHeight() {
132e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        return mHeight;
133e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
134e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
135f61970fc79e9c5cf340fa942597628242361864aRomain Guy    @Override
136f61970fc79e9c5cf340fa942597628242361864aRomain Guy    public int getMaximumBitmapWidth() {
137f61970fc79e9c5cf340fa942597628242361864aRomain Guy        return nGetMaximumTextureWidth();
138f61970fc79e9c5cf340fa942597628242361864aRomain Guy    }
139f61970fc79e9c5cf340fa942597628242361864aRomain Guy
140f61970fc79e9c5cf340fa942597628242361864aRomain Guy    @Override
141f61970fc79e9c5cf340fa942597628242361864aRomain Guy    public int getMaximumBitmapHeight() {
142f61970fc79e9c5cf340fa942597628242361864aRomain Guy        return nGetMaximumTextureHeight();
143f61970fc79e9c5cf340fa942597628242361864aRomain Guy    }
144f61970fc79e9c5cf340fa942597628242361864aRomain Guy
145f61970fc79e9c5cf340fa942597628242361864aRomain Guy    private static native int nGetMaximumTextureWidth();
146530041d3191ce817832a0108514617768e43cda6Romain Guy    private static native int nGetMaximumTextureHeight();
147f61970fc79e9c5cf340fa942597628242361864aRomain Guy
148e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
149e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // Setup
150e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
151e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
152e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
1538afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    public void insertReorderBarrier() {
1548dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nInsertReorderBarrier(mNativeCanvasWrapper, true);
1558afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    }
1568afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
1578afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    @Override
1588afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    public void insertInorderBarrier() {
1598dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nInsertReorderBarrier(mNativeCanvasWrapper, false);
1608afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    }
1618afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
1628afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    private static native void nInsertReorderBarrier(long renderer, boolean enableReorder);
1638afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
164530041d3191ce817832a0108514617768e43cda6Romain Guy    ///////////////////////////////////////////////////////////////////////////
165530041d3191ce817832a0108514617768e43cda6Romain Guy    // Functor
166530041d3191ce817832a0108514617768e43cda6Romain Guy    ///////////////////////////////////////////////////////////////////////////
167530041d3191ce817832a0108514617768e43cda6Romain Guy
168f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    /**
169cd1c3eba69d044b551cededad75474038f919890John Reck     * Records the functor specified with the drawGLFunction function pointer. This is
170cd1c3eba69d044b551cededad75474038f919890John Reck     * functionality used by webview for calling into their renderer from our display lists.
171f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     *
172f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     * @param drawGLFunction A native function pointer
173f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     */
17457616d3e55ffd3a4dbfd3a721b078a09fbe6d05cNarayan Kamath    public void callDrawGLFunction2(long drawGLFunction) {
175cd1c3eba69d044b551cededad75474038f919890John Reck        nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunction, null);
176daf98e941e140e8739458126640183b9f296a2abChet Haase    }
177daf98e941e140e8739458126640183b9f296a2abChet Haase
178cd1c3eba69d044b551cededad75474038f919890John Reck    /**
179cd1c3eba69d044b551cededad75474038f919890John Reck     * Records the functor specified with the drawGLFunction function pointer. This is
180cd1c3eba69d044b551cededad75474038f919890John Reck     * functionality used by webview for calling into their renderer from our display lists.
181cd1c3eba69d044b551cededad75474038f919890John Reck     *
182cd1c3eba69d044b551cededad75474038f919890John Reck     * @param drawGLFunction A native function pointer
183cd1c3eba69d044b551cededad75474038f919890John Reck     * @param releasedCallback Called when the display list is destroyed, and thus
184cd1c3eba69d044b551cededad75474038f919890John Reck     * the functor is no longer referenced by this canvas's display list.
185cd1c3eba69d044b551cededad75474038f919890John Reck     *
186cd1c3eba69d044b551cededad75474038f919890John Reck     * NOTE: The callback does *not* necessarily mean that there are no longer
187cd1c3eba69d044b551cededad75474038f919890John Reck     * any references to the functor, just that the reference from this specific
188cd1c3eba69d044b551cededad75474038f919890John Reck     * canvas's display list has been released.
189cd1c3eba69d044b551cededad75474038f919890John Reck     */
1904afbed15f3b4f88c0190bbb89deba7a6ceae2da7John Reck    public void drawGLFunctor2(long drawGLFunctor, @Nullable Runnable releasedCallback) {
191cd1c3eba69d044b551cededad75474038f919890John Reck        nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunctor, releasedCallback);
192cd1c3eba69d044b551cededad75474038f919890John Reck    }
193cd1c3eba69d044b551cededad75474038f919890John Reck
194cd1c3eba69d044b551cededad75474038f919890John Reck    private static native void nCallDrawGLFunction(long renderer,
195cd1c3eba69d044b551cededad75474038f919890John Reck            long drawGLFunction, Runnable releasedCallback);
196daf98e941e140e8739458126640183b9f296a2abChet Haase
197bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy    ///////////////////////////////////////////////////////////////////////////
198b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    // Display list
199b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    ///////////////////////////////////////////////////////////////////////////
200b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
20144fd8d24f761f82d21e9b00932648a1b6bf91449John Reck    protected static native long nFinishRecording(long renderer);
20265b345fa22b878e141b8fd8ece9c208df00fa40fRomain Guy
203f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    /**
204f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     * Draws the specified display list onto this canvas. The display list can only
205f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     * be drawn if {@link android.view.RenderNode#isValid()} returns true.
206f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     *
207956f340aacc7d8fc2d10f776551f13fde2d8d3abChris Craik     * @param renderNode The RenderNode to draw.
208f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     */
209f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    public void drawRenderNode(RenderNode renderNode) {
210956f340aacc7d8fc2d10f776551f13fde2d8d3abChris Craik        nDrawRenderNode(mNativeCanvasWrapper, renderNode.getNativeDisplayList());
211f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    }
212f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik
213956f340aacc7d8fc2d10f776551f13fde2d8d3abChris Craik    private static native void nDrawRenderNode(long renderer, long renderNode);
214da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy
215e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
2166c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    // Hardware layer
2176c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    ///////////////////////////////////////////////////////////////////////////
218051910b9f998030dacb8a0722588cc715813fde1Raph Levien
219f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    /**
220f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     * Draws the specified layer onto this canvas.
221f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     *
222f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     * @param layer The layer to composite on this canvas
223f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     */
2243aadd60521960be063ee06208562ccb63dc414e3Chris Craik    void drawHardwareLayer(HardwareLayer layer) {
2253aadd60521960be063ee06208562ccb63dc414e3Chris Craik        nDrawLayer(mNativeCanvasWrapper, layer.getLayerHandle());
2266c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    }
2276c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
2283aadd60521960be063ee06208562ccb63dc414e3Chris Craik    private static native void nDrawLayer(long renderer, long layer);
229aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy
2306c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    ///////////////////////////////////////////////////////////////////////////
231e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // Drawing
232e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
233e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
23452244fff29042926e21fa897ef5ab11148e35299John Reck    public void drawCircle(CanvasProperty<Float> cx, CanvasProperty<Float> cy,
23552244fff29042926e21fa897ef5ab11148e35299John Reck            CanvasProperty<Float> radius, CanvasProperty<Paint> paint) {
2368dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nDrawCircle(mNativeCanvasWrapper, cx.getNativeContainer(), cy.getNativeContainer(),
23752244fff29042926e21fa897ef5ab11148e35299John Reck                radius.getNativeContainer(), paint.getNativeContainer());
23852244fff29042926e21fa897ef5ab11148e35299John Reck    }
23952244fff29042926e21fa897ef5ab11148e35299John Reck
24052244fff29042926e21fa897ef5ab11148e35299John Reck    private static native void nDrawCircle(long renderer, long propCx,
24152244fff29042926e21fa897ef5ab11148e35299John Reck            long propCy, long propRadius, long propPaint);
24252244fff29042926e21fa897ef5ab11148e35299John Reck
243072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi    public void drawRoundRect(CanvasProperty<Float> left, CanvasProperty<Float> top,
244072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi            CanvasProperty<Float> right, CanvasProperty<Float> bottom, CanvasProperty<Float> rx,
245072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi            CanvasProperty<Float> ry, CanvasProperty<Paint> paint) {
2468dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nDrawRoundRect(mNativeCanvasWrapper, left.getNativeContainer(), top.getNativeContainer(),
247072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi                right.getNativeContainer(), bottom.getNativeContainer(),
248072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi                rx.getNativeContainer(), ry.getNativeContainer(),
249072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi                paint.getNativeContainer());
250072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi    }
251072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi
252072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi    private static native void nDrawRoundRect(long renderer, long propLeft, long propTop,
253072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi            long propRight, long propBottom, long propRx, long propRy, long propPaint);
2543d8298e1a8b35dadb0a383aadb9a545ecab463e2sergeyv
2553d8298e1a8b35dadb0a383aadb9a545ecab463e2sergeyv    @Override
2563d8298e1a8b35dadb0a383aadb9a545ecab463e2sergeyv    protected void throwIfCannotDraw(Bitmap bitmap) {
2573d8298e1a8b35dadb0a383aadb9a545ecab463e2sergeyv        super.throwIfCannotDraw(bitmap);
2583d8298e1a8b35dadb0a383aadb9a545ecab463e2sergeyv        int bitmapSize = bitmap.getByteCount();
2593d8298e1a8b35dadb0a383aadb9a545ecab463e2sergeyv        if (bitmapSize > MAX_BITMAP_SIZE) {
2603d8298e1a8b35dadb0a383aadb9a545ecab463e2sergeyv            throw new RuntimeException(
2613d8298e1a8b35dadb0a383aadb9a545ecab463e2sergeyv                    "Canvas: trying to draw too large(" + bitmapSize + "bytes) bitmap.");
2623d8298e1a8b35dadb0a383aadb9a545ecab463e2sergeyv        }
2633d8298e1a8b35dadb0a383aadb9a545ecab463e2sergeyv    }
264e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy}
265