DisplayListCanvas.java revision c9070ebd13263a341511cf779087a46750021196
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;
20e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.Bitmap;
2152244fff29042926e21fa897ef5ab11148e35299John Reckimport android.graphics.CanvasProperty;
223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyimport android.graphics.NinePatch;
23e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.Paint;
24e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.Path;
25e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.Picture;
26e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.Rect;
27e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.RectF;
28c9070ebd13263a341511cf779087a46750021196Chris Craikimport android.util.Pools.SynchronizedPool;
29e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
30e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy/**
31c9070ebd13263a341511cf779087a46750021196Chris Craik * An implementation of a GL canvas that records drawing operations.
32c9070ebd13263a341511cf779087a46750021196Chris Craik * This is intended for use with a DisplayList. This class keeps a list of all the Paint and
33c9070ebd13263a341511cf779087a46750021196Chris Craik * Bitmap objects that it draws, preventing the backing memory of Bitmaps from being freed while
34c9070ebd13263a341511cf779087a46750021196Chris Craik * the DisplayList is still holding a native reference to the memory.
35e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy */
36c9070ebd13263a341511cf779087a46750021196Chris Craikclass DisplayListCanvas extends HardwareCanvas {
37c9070ebd13263a341511cf779087a46750021196Chris Craik    // The recording canvas pool should be large enough to handle a deeply nested
38c9070ebd13263a341511cf779087a46750021196Chris Craik    // view hierarchy because display lists are generated recursively.
39c9070ebd13263a341511cf779087a46750021196Chris Craik    private static final int POOL_LIMIT = 25;
40c9070ebd13263a341511cf779087a46750021196Chris Craik
41c9070ebd13263a341511cf779087a46750021196Chris Craik    private static final SynchronizedPool<DisplayListCanvas> sPool =
42c9070ebd13263a341511cf779087a46750021196Chris Craik            new SynchronizedPool<DisplayListCanvas>(POOL_LIMIT);
43c9070ebd13263a341511cf779087a46750021196Chris Craik
44c9070ebd13263a341511cf779087a46750021196Chris Craik    RenderNode mNode;
45e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    private int mWidth;
46e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    private int mHeight;
47051910b9f998030dacb8a0722588cc715813fde1Raph Levien
48051910b9f998030dacb8a0722588cc715813fde1Raph Levien
49c9070ebd13263a341511cf779087a46750021196Chris Craik    static DisplayListCanvas obtain(@NonNull RenderNode node) {
50c9070ebd13263a341511cf779087a46750021196Chris Craik        if (node == null) throw new IllegalArgumentException("node cannot be null");
51c9070ebd13263a341511cf779087a46750021196Chris Craik        DisplayListCanvas canvas = sPool.acquire();
52c9070ebd13263a341511cf779087a46750021196Chris Craik        if (canvas == null) {
53c9070ebd13263a341511cf779087a46750021196Chris Craik            canvas = new DisplayListCanvas();
54c9070ebd13263a341511cf779087a46750021196Chris Craik        }
55c9070ebd13263a341511cf779087a46750021196Chris Craik        canvas.mNode = node;
56c9070ebd13263a341511cf779087a46750021196Chris Craik        return canvas;
57c9070ebd13263a341511cf779087a46750021196Chris Craik    }
58c9070ebd13263a341511cf779087a46750021196Chris Craik
59c9070ebd13263a341511cf779087a46750021196Chris Craik    void recycle() {
60c9070ebd13263a341511cf779087a46750021196Chris Craik        mNode = null;
61c9070ebd13263a341511cf779087a46750021196Chris Craik        sPool.release(this);
62c9070ebd13263a341511cf779087a46750021196Chris Craik    }
63c9070ebd13263a341511cf779087a46750021196Chris Craik
64c9070ebd13263a341511cf779087a46750021196Chris Craik    long finishRecording() {
65c9070ebd13263a341511cf779087a46750021196Chris Craik        return nFinishRecording(mNativeCanvasWrapper);
66c9070ebd13263a341511cf779087a46750021196Chris Craik    }
67c9070ebd13263a341511cf779087a46750021196Chris Craik
68c9070ebd13263a341511cf779087a46750021196Chris Craik    @Override
69c9070ebd13263a341511cf779087a46750021196Chris Craik    public boolean isRecordingFor(Object o) {
70c9070ebd13263a341511cf779087a46750021196Chris Craik        return o == mNode;
71c9070ebd13263a341511cf779087a46750021196Chris Craik    }
726926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy
73163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    ///////////////////////////////////////////////////////////////////////////
74163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    // JNI
75163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    ///////////////////////////////////////////////////////////////////////////
76163935113919a184122b8b3bd672ef08c8df65dcRomain Guy
77163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    private static native boolean nIsAvailable();
78163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    private static boolean sIsAvailable = nIsAvailable();
79163935113919a184122b8b3bd672ef08c8df65dcRomain Guy
80163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    static boolean isAvailable() {
81163935113919a184122b8b3bd672ef08c8df65dcRomain Guy        return sIsAvailable;
82163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    }
83e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
84e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
85e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // Constructors
86e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
87b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
88c9070ebd13263a341511cf779087a46750021196Chris Craik
89c9070ebd13263a341511cf779087a46750021196Chris Craik    private DisplayListCanvas() {
908dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        super(nCreateDisplayListRenderer());
91e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
92b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
9336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native long nCreateDisplayListRenderer();
94ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
95ba9b613437c34873fa95800a25fc51720638267cChris Craik    public static void setProperty(String name, String value) {
96ba9b613437c34873fa95800a25fc51720638267cChris Craik        nSetProperty(name, value);
97ba9b613437c34873fa95800a25fc51720638267cChris Craik    }
98ba9b613437c34873fa95800a25fc51720638267cChris Craik
99ba9b613437c34873fa95800a25fc51720638267cChris Craik    private static native void nSetProperty(String name, String value);
100ba9b613437c34873fa95800a25fc51720638267cChris Craik
101e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
102e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // Canvas management
103e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
104e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
105e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
106e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public boolean isOpaque() {
1078dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        return false;
108e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
109e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
110e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
111e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public int getWidth() {
112e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        return mWidth;
113e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
114e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
115e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
116e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public int getHeight() {
117e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        return mHeight;
118e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
119e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
120f61970fc79e9c5cf340fa942597628242361864aRomain Guy    @Override
121f61970fc79e9c5cf340fa942597628242361864aRomain Guy    public int getMaximumBitmapWidth() {
122f61970fc79e9c5cf340fa942597628242361864aRomain Guy        return nGetMaximumTextureWidth();
123f61970fc79e9c5cf340fa942597628242361864aRomain Guy    }
124f61970fc79e9c5cf340fa942597628242361864aRomain Guy
125f61970fc79e9c5cf340fa942597628242361864aRomain Guy    @Override
126f61970fc79e9c5cf340fa942597628242361864aRomain Guy    public int getMaximumBitmapHeight() {
127f61970fc79e9c5cf340fa942597628242361864aRomain Guy        return nGetMaximumTextureHeight();
128f61970fc79e9c5cf340fa942597628242361864aRomain Guy    }
129f61970fc79e9c5cf340fa942597628242361864aRomain Guy
130f61970fc79e9c5cf340fa942597628242361864aRomain Guy    private static native int nGetMaximumTextureWidth();
131530041d3191ce817832a0108514617768e43cda6Romain Guy    private static native int nGetMaximumTextureHeight();
132f61970fc79e9c5cf340fa942597628242361864aRomain Guy
1332bf68f063b0077ddef6ebfe54f2ae5e063c2c229Romain Guy    /**
1342bf68f063b0077ddef6ebfe54f2ae5e063c2c229Romain Guy     * Returns the native OpenGLRenderer object.
1352bf68f063b0077ddef6ebfe54f2ae5e063c2c229Romain Guy     */
13636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    long getRenderer() {
1378dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        return mNativeCanvasWrapper;
1382bf68f063b0077ddef6ebfe54f2ae5e063c2c229Romain Guy    }
1392bf68f063b0077ddef6ebfe54f2ae5e063c2c229Romain Guy
140e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
141e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // Setup
142e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
143e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
144e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
145e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void setViewport(int width, int height) {
146e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        mWidth = width;
147e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        mHeight = height;
148e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
1498dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nSetViewport(mNativeCanvasWrapper, width, height);
150e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
151051910b9f998030dacb8a0722588cc715813fde1Raph Levien
152cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    private static native void nSetViewport(long renderer,
153cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik            int width, int height);
154cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik
155cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    @Override
156cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    public void setHighContrastText(boolean highContrastText) {
1578dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nSetHighContrastText(mNativeCanvasWrapper, highContrastText);
158cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    }
159cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik
160cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    private static native void nSetHighContrastText(long renderer, boolean highContrastText);
161e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
162b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    @Override
1638afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    public void insertReorderBarrier() {
1648dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nInsertReorderBarrier(mNativeCanvasWrapper, true);
1658afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    }
1668afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
1678afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    @Override
1688afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    public void insertInorderBarrier() {
1698dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nInsertReorderBarrier(mNativeCanvasWrapper, false);
1708afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    }
1718afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
1728afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    private static native void nInsertReorderBarrier(long renderer, boolean enableReorder);
1738afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
1748afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    @Override
175107843de4507b3511006cb9c77b8d0364374385aTom Hudson    public void onPreDraw(Rect dirty) {
1767d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy        if (dirty != null) {
1778dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            nPrepareDirty(mNativeCanvasWrapper, dirty.left, dirty.top, dirty.right, dirty.bottom);
1787d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy        } else {
1798dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            nPrepare(mNativeCanvasWrapper);
1807d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy        }
181e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
182b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy
1838dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    private static native void nPrepare(long renderer);
1848dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    private static native void nPrepareDirty(long renderer, int left, int top, int right, int bottom);
185e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
186b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    @Override
187b35ab7b72967adcfd01cec483a705dafe8b951d1Gilles Debunne    public void onPostDraw() {
1888dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nFinish(mNativeCanvasWrapper);
189b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy    }
1909ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy
19136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nFinish(long renderer);
192b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy
193530041d3191ce817832a0108514617768e43cda6Romain Guy    ///////////////////////////////////////////////////////////////////////////
194530041d3191ce817832a0108514617768e43cda6Romain Guy    // Functor
195530041d3191ce817832a0108514617768e43cda6Romain Guy    ///////////////////////////////////////////////////////////////////////////
196530041d3191ce817832a0108514617768e43cda6Romain Guy
197da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy    @Override
19857616d3e55ffd3a4dbfd3a721b078a09fbe6d05cNarayan Kamath    public void callDrawGLFunction2(long drawGLFunction) {
1998dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunction);
200daf98e941e140e8739458126640183b9f296a2abChet Haase    }
201daf98e941e140e8739458126640183b9f296a2abChet Haase
202107843de4507b3511006cb9c77b8d0364374385aTom Hudson    private static native void nCallDrawGLFunction(long renderer, long drawGLFunction);
203daf98e941e140e8739458126640183b9f296a2abChet Haase
204bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy    ///////////////////////////////////////////////////////////////////////////
205b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    // Display list
206b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    ///////////////////////////////////////////////////////////////////////////
207b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
20844fd8d24f761f82d21e9b00932648a1b6bf91449John Reck    protected static native long nFinishRecording(long renderer);
20965b345fa22b878e141b8fd8ece9c208df00fa40fRomain Guy
21052036b19a5f82bc4d75cfcbff99c65df8d25a99bRomain Guy    @Override
211107843de4507b3511006cb9c77b8d0364374385aTom Hudson    public void drawRenderNode(RenderNode renderNode, int flags) {
2128dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nDrawRenderNode(mNativeCanvasWrapper, renderNode.getNativeDisplayList(), flags);
213b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    }
214b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
215107843de4507b3511006cb9c77b8d0364374385aTom Hudson    private static native void nDrawRenderNode(long renderer, long renderNode,
216107843de4507b3511006cb9c77b8d0364374385aTom Hudson            int flags);
217da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy
218e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
2196c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    // Hardware layer
2206c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    ///////////////////////////////////////////////////////////////////////////
221051910b9f998030dacb8a0722588cc715813fde1Raph Levien
222ada830f639591b99c3e40de22b07296c7932a33fRomain Guy    void drawHardwareLayer(HardwareLayer layer, float x, float y, Paint paint) {
223a4e16c58c9e3c983251e0475125a2a6f5bec2dbfChris Craik        layer.setLayerPaint(paint);
2248dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nDrawLayer(mNativeCanvasWrapper, layer.getLayerHandle(), x, y);
2256c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    }
2266c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
22736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nDrawLayer(long renderer, long layer, float x, float y);
228aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy
2296c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    ///////////////////////////////////////////////////////////////////////////
230e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // Drawing
231e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
232e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
2338dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    // TODO: move to Canvas.java
234e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
235f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy    public void drawPatch(NinePatch patch, Rect dst, Paint paint) {
236f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy        Bitmap bitmap = patch.getBitmap();
2371abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik        throwIfCannotDraw(bitmap);
238dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger        final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
239f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck        nDrawPatch(mNativeCanvasWrapper, bitmap.getSkBitmap(), patch.mNativeChunk,
24076d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger                dst.left, dst.top, dst.right, dst.bottom, nativePaint);
241f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy    }
242f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy
2438dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    // TODO: move to Canvas.java
244f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy    @Override
2453b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public void drawPatch(NinePatch patch, RectF dst, Paint paint) {
2463b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        Bitmap bitmap = patch.getBitmap();
2471abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik        throwIfCannotDraw(bitmap);
248dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger        final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
249f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck        nDrawPatch(mNativeCanvasWrapper, bitmap.getSkBitmap(), patch.mNativeChunk,
25076d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger                dst.left, dst.top, dst.right, dst.bottom, nativePaint);
251deba785f122a47915756ffd991f5540d952cf937Romain Guy    }
252deba785f122a47915756ffd991f5540d952cf937Romain Guy
253f29d5a5b211786248d0557157c304c5fff428bd4Derek Sollenberger    private static native void nDrawPatch(long renderer, long bitmap, long chunk,
25436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat            float left, float top, float right, float bottom, long paint);
255deba785f122a47915756ffd991f5540d952cf937Romain Guy
256deba785f122a47915756ffd991f5540d952cf937Romain Guy    @Override
25752244fff29042926e21fa897ef5ab11148e35299John Reck    public void drawCircle(CanvasProperty<Float> cx, CanvasProperty<Float> cy,
25852244fff29042926e21fa897ef5ab11148e35299John Reck            CanvasProperty<Float> radius, CanvasProperty<Paint> paint) {
2598dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nDrawCircle(mNativeCanvasWrapper, cx.getNativeContainer(), cy.getNativeContainer(),
26052244fff29042926e21fa897ef5ab11148e35299John Reck                radius.getNativeContainer(), paint.getNativeContainer());
26152244fff29042926e21fa897ef5ab11148e35299John Reck    }
26252244fff29042926e21fa897ef5ab11148e35299John Reck
26352244fff29042926e21fa897ef5ab11148e35299John Reck    private static native void nDrawCircle(long renderer, long propCx,
26452244fff29042926e21fa897ef5ab11148e35299John Reck            long propCy, long propRadius, long propPaint);
26552244fff29042926e21fa897ef5ab11148e35299John Reck
26652244fff29042926e21fa897ef5ab11148e35299John Reck    @Override
267072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi    public void drawRoundRect(CanvasProperty<Float> left, CanvasProperty<Float> top,
268072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi            CanvasProperty<Float> right, CanvasProperty<Float> bottom, CanvasProperty<Float> rx,
269072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi            CanvasProperty<Float> ry, CanvasProperty<Paint> paint) {
2708dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nDrawRoundRect(mNativeCanvasWrapper, left.getNativeContainer(), top.getNativeContainer(),
271072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi                right.getNativeContainer(), bottom.getNativeContainer(),
272072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi                rx.getNativeContainer(), ry.getNativeContainer(),
273072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi                paint.getNativeContainer());
274072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi    }
275072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi
276072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi    private static native void nDrawRoundRect(long renderer, long propLeft, long propTop,
277072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi            long propRight, long propBottom, long propRx, long propRy, long propPaint);
278072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi
2798dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    // TODO: move this optimization to Canvas.java
280e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
281e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawPath(Path path, Paint paint) {
282d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III        if (path.isSimplePath) {
283d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III            if (path.rects != null) {
2848dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson                nDrawRects(mNativeCanvasWrapper, path.rects.mNativeRegion, paint.getNativeInstance());
285a48a1a87ba17f20f7006eaab21dcedf86c015c13Romain Guy            }
286d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III        } else {
2878dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            super.drawPath(path, paint);
288a48a1a87ba17f20f7006eaab21dcedf86c015c13Romain Guy        }
289e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
290e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
29136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nDrawRects(long renderer, long region, long paint);
2927fbcc0492fca03857e3c45064f4aa040af817d55Romain Guy
293e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
294e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawPicture(Picture picture) {
29575582e889d4895483309e38364266073be6d46b8Romain Guy        picture.endRecording();
29675582e889d4895483309e38364266073be6d46b8Romain Guy        // TODO: Implement rendering
297e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
298e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy}
299