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;
21f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craikimport android.graphics.Canvas;
2252244fff29042926e21fa897ef5ab11148e35299John Reckimport android.graphics.CanvasProperty;
233b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyimport android.graphics.NinePatch;
24e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.Paint;
25e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.Path;
26e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.Picture;
27e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.Rect;
28e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyimport android.graphics.RectF;
29c9070ebd13263a341511cf779087a46750021196Chris Craikimport android.util.Pools.SynchronizedPool;
30e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
31e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy/**
32c9070ebd13263a341511cf779087a46750021196Chris Craik * An implementation of a GL canvas that records drawing operations.
33c9070ebd13263a341511cf779087a46750021196Chris Craik * This is intended for use with a DisplayList. This class keeps a list of all the Paint and
34c9070ebd13263a341511cf779087a46750021196Chris Craik * Bitmap objects that it draws, preventing the backing memory of Bitmaps from being freed while
35c9070ebd13263a341511cf779087a46750021196Chris Craik * the DisplayList is still holding a native reference to the memory.
36f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik *
37f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik * @hide
38e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy */
39f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craikpublic class DisplayListCanvas extends Canvas {
40c9070ebd13263a341511cf779087a46750021196Chris Craik    // The recording canvas pool should be large enough to handle a deeply nested
41c9070ebd13263a341511cf779087a46750021196Chris Craik    // view hierarchy because display lists are generated recursively.
42c9070ebd13263a341511cf779087a46750021196Chris Craik    private static final int POOL_LIMIT = 25;
43c9070ebd13263a341511cf779087a46750021196Chris Craik
44c9070ebd13263a341511cf779087a46750021196Chris Craik    private static final SynchronizedPool<DisplayListCanvas> sPool =
45c9070ebd13263a341511cf779087a46750021196Chris Craik            new SynchronizedPool<DisplayListCanvas>(POOL_LIMIT);
46c9070ebd13263a341511cf779087a46750021196Chris Craik
47c9070ebd13263a341511cf779087a46750021196Chris Craik    RenderNode mNode;
48e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    private int mWidth;
49e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    private int mHeight;
50051910b9f998030dacb8a0722588cc715813fde1Raph Levien
51c9070ebd13263a341511cf779087a46750021196Chris Craik    static DisplayListCanvas obtain(@NonNull RenderNode node) {
52c9070ebd13263a341511cf779087a46750021196Chris Craik        if (node == null) throw new IllegalArgumentException("node cannot be null");
53c9070ebd13263a341511cf779087a46750021196Chris Craik        DisplayListCanvas canvas = sPool.acquire();
54c9070ebd13263a341511cf779087a46750021196Chris Craik        if (canvas == null) {
55c9070ebd13263a341511cf779087a46750021196Chris Craik            canvas = new DisplayListCanvas();
56c9070ebd13263a341511cf779087a46750021196Chris Craik        }
57c9070ebd13263a341511cf779087a46750021196Chris Craik        canvas.mNode = node;
58c9070ebd13263a341511cf779087a46750021196Chris Craik        return canvas;
59c9070ebd13263a341511cf779087a46750021196Chris Craik    }
60c9070ebd13263a341511cf779087a46750021196Chris Craik
61c9070ebd13263a341511cf779087a46750021196Chris Craik    void recycle() {
62c9070ebd13263a341511cf779087a46750021196Chris Craik        mNode = null;
63c9070ebd13263a341511cf779087a46750021196Chris Craik        sPool.release(this);
64c9070ebd13263a341511cf779087a46750021196Chris Craik    }
65c9070ebd13263a341511cf779087a46750021196Chris Craik
66c9070ebd13263a341511cf779087a46750021196Chris Craik    long finishRecording() {
67c9070ebd13263a341511cf779087a46750021196Chris Craik        return nFinishRecording(mNativeCanvasWrapper);
68c9070ebd13263a341511cf779087a46750021196Chris Craik    }
69c9070ebd13263a341511cf779087a46750021196Chris Craik
70c9070ebd13263a341511cf779087a46750021196Chris Craik    @Override
71c9070ebd13263a341511cf779087a46750021196Chris Craik    public boolean isRecordingFor(Object o) {
72c9070ebd13263a341511cf779087a46750021196Chris Craik        return o == mNode;
73c9070ebd13263a341511cf779087a46750021196Chris Craik    }
746926c72e25b8dec3dd4b84af0819fa1937ae7296Romain Guy
75163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    ///////////////////////////////////////////////////////////////////////////
76163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    // JNI
77163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    ///////////////////////////////////////////////////////////////////////////
78163935113919a184122b8b3bd672ef08c8df65dcRomain Guy
79163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    private static native boolean nIsAvailable();
80163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    private static boolean sIsAvailable = nIsAvailable();
81163935113919a184122b8b3bd672ef08c8df65dcRomain Guy
82163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    static boolean isAvailable() {
83163935113919a184122b8b3bd672ef08c8df65dcRomain Guy        return sIsAvailable;
84163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    }
85e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
86e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
87e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // Constructors
88e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
89b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
90c9070ebd13263a341511cf779087a46750021196Chris Craik    private DisplayListCanvas() {
91db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik        super(nCreateDisplayListCanvas());
929c08ee0f6cbfce4696acb166fcfbf424d8efcb31Chris Craik        mDensity = 0; // disable bitmap density scaling
93e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
94b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
95db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik    private static native long nCreateDisplayListCanvas();
96ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
97e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
98e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // Canvas management
99e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
100e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
1019c08ee0f6cbfce4696acb166fcfbf424d8efcb31Chris Craik
1029c08ee0f6cbfce4696acb166fcfbf424d8efcb31Chris Craik    @Override
1039c08ee0f6cbfce4696acb166fcfbf424d8efcb31Chris Craik    public void setDensity(int density) {
1049c08ee0f6cbfce4696acb166fcfbf424d8efcb31Chris Craik        // drop silently, since DisplayListCanvas doesn't perform density scaling
1059c08ee0f6cbfce4696acb166fcfbf424d8efcb31Chris Craik    }
1069c08ee0f6cbfce4696acb166fcfbf424d8efcb31Chris Craik
107e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
108f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    public boolean isHardwareAccelerated() {
109f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik        return true;
110f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    }
111f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik
112f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    @Override
113f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    public void setBitmap(Bitmap bitmap) {
114f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik        throw new UnsupportedOperationException();
115f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    }
116f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik
117f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    @Override
118e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public boolean isOpaque() {
1198dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        return false;
120e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
121e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
122e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
123e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public int getWidth() {
124e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        return mWidth;
125e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
126e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
127e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
128e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public int getHeight() {
129e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        return mHeight;
130e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
131e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
132f61970fc79e9c5cf340fa942597628242361864aRomain Guy    @Override
133f61970fc79e9c5cf340fa942597628242361864aRomain Guy    public int getMaximumBitmapWidth() {
134f61970fc79e9c5cf340fa942597628242361864aRomain Guy        return nGetMaximumTextureWidth();
135f61970fc79e9c5cf340fa942597628242361864aRomain Guy    }
136f61970fc79e9c5cf340fa942597628242361864aRomain Guy
137f61970fc79e9c5cf340fa942597628242361864aRomain Guy    @Override
138f61970fc79e9c5cf340fa942597628242361864aRomain Guy    public int getMaximumBitmapHeight() {
139f61970fc79e9c5cf340fa942597628242361864aRomain Guy        return nGetMaximumTextureHeight();
140f61970fc79e9c5cf340fa942597628242361864aRomain Guy    }
141f61970fc79e9c5cf340fa942597628242361864aRomain Guy
142f61970fc79e9c5cf340fa942597628242361864aRomain Guy    private static native int nGetMaximumTextureWidth();
143530041d3191ce817832a0108514617768e43cda6Romain Guy    private static native int nGetMaximumTextureHeight();
144f61970fc79e9c5cf340fa942597628242361864aRomain Guy
1452bf68f063b0077ddef6ebfe54f2ae5e063c2c229Romain Guy    /**
1462bf68f063b0077ddef6ebfe54f2ae5e063c2c229Romain Guy     * Returns the native OpenGLRenderer object.
1472bf68f063b0077ddef6ebfe54f2ae5e063c2c229Romain Guy     */
14836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    long getRenderer() {
1498dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        return mNativeCanvasWrapper;
1502bf68f063b0077ddef6ebfe54f2ae5e063c2c229Romain Guy    }
1512bf68f063b0077ddef6ebfe54f2ae5e063c2c229Romain Guy
152e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
153e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // Setup
154e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
155e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
156e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
157e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void setViewport(int width, int height) {
158e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        mWidth = width;
159e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy        mHeight = height;
160e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
1618dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nSetViewport(mNativeCanvasWrapper, width, height);
162e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
163051910b9f998030dacb8a0722588cc715813fde1Raph Levien
164cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    private static native void nSetViewport(long renderer,
165cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik            int width, int height);
166cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik
167cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    @Override
168cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    public void setHighContrastText(boolean highContrastText) {
1698dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nSetHighContrastText(mNativeCanvasWrapper, highContrastText);
170cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    }
171cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik
172cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    private static native void nSetHighContrastText(long renderer, boolean highContrastText);
173e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
174b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    @Override
1758afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    public void insertReorderBarrier() {
1768dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nInsertReorderBarrier(mNativeCanvasWrapper, true);
1778afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    }
1788afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
1798afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    @Override
1808afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    public void insertInorderBarrier() {
1818dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nInsertReorderBarrier(mNativeCanvasWrapper, false);
1828afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    }
1838afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
1848afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    private static native void nInsertReorderBarrier(long renderer, boolean enableReorder);
1858afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
186f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    /**
187f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     * Invoked before any drawing operation is performed in this canvas.
188f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     *
189f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     * @param dirty The dirty rectangle to update, can be null.
190f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     */
191107843de4507b3511006cb9c77b8d0364374385aTom Hudson    public void onPreDraw(Rect dirty) {
1927d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy        if (dirty != null) {
1938dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            nPrepareDirty(mNativeCanvasWrapper, dirty.left, dirty.top, dirty.right, dirty.bottom);
1947d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy        } else {
1958dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            nPrepare(mNativeCanvasWrapper);
1967d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy        }
197e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
198b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy
1998dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    private static native void nPrepare(long renderer);
2008dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    private static native void nPrepareDirty(long renderer, int left, int top, int right, int bottom);
201e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
202f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    /**
203f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     * Invoked after all drawing operation have been performed.
204f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     */
205b35ab7b72967adcfd01cec483a705dafe8b951d1Gilles Debunne    public void onPostDraw() {
2068dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nFinish(mNativeCanvasWrapper);
207b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy    }
2089ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy
20936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nFinish(long renderer);
210b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy
211530041d3191ce817832a0108514617768e43cda6Romain Guy    ///////////////////////////////////////////////////////////////////////////
212530041d3191ce817832a0108514617768e43cda6Romain Guy    // Functor
213530041d3191ce817832a0108514617768e43cda6Romain Guy    ///////////////////////////////////////////////////////////////////////////
214530041d3191ce817832a0108514617768e43cda6Romain Guy
215f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    /**
216f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     * Calls the function specified with the drawGLFunction function pointer. This is
217f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     * functionality used by webkit for calling into their renderer from our display lists.
218f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     * This function may return true if an invalidation is needed after the call.
219f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     *
220f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     * @param drawGLFunction A native function pointer
221f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     */
22257616d3e55ffd3a4dbfd3a721b078a09fbe6d05cNarayan Kamath    public void callDrawGLFunction2(long drawGLFunction) {
2238dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunction);
224daf98e941e140e8739458126640183b9f296a2abChet Haase    }
225daf98e941e140e8739458126640183b9f296a2abChet Haase
226107843de4507b3511006cb9c77b8d0364374385aTom Hudson    private static native void nCallDrawGLFunction(long renderer, long drawGLFunction);
227daf98e941e140e8739458126640183b9f296a2abChet Haase
228bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy    ///////////////////////////////////////////////////////////////////////////
229b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    // Display list
230b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy    ///////////////////////////////////////////////////////////////////////////
231b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
23244fd8d24f761f82d21e9b00932648a1b6bf91449John Reck    protected static native long nFinishRecording(long renderer);
23365b345fa22b878e141b8fd8ece9c208df00fa40fRomain Guy
234f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    /**
235f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     * Draws the specified display list onto this canvas. The display list can only
236f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     * be drawn if {@link android.view.RenderNode#isValid()} returns true.
237f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     *
238956f340aacc7d8fc2d10f776551f13fde2d8d3abChris Craik     * @param renderNode The RenderNode to draw.
239f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     */
240f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    public void drawRenderNode(RenderNode renderNode) {
241956f340aacc7d8fc2d10f776551f13fde2d8d3abChris Craik        nDrawRenderNode(mNativeCanvasWrapper, renderNode.getNativeDisplayList());
242f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    }
243f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik
244956f340aacc7d8fc2d10f776551f13fde2d8d3abChris Craik    private static native void nDrawRenderNode(long renderer, long renderNode);
245da8532c6f48b4c10b5e2ccb9e08690341efa1616Romain Guy
246e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
2476c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    // Hardware layer
2486c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    ///////////////////////////////////////////////////////////////////////////
249051910b9f998030dacb8a0722588cc715813fde1Raph Levien
250f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik    /**
251f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     * Draws the specified layer onto this canvas.
252f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     *
253f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     * @param layer The layer to composite on this canvas
254f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     * @param x The left coordinate of the layer
255f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     * @param y The top coordinate of the layer
256f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     * @param paint The paint used to draw the layer
257f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik     */
258ada830f639591b99c3e40de22b07296c7932a33fRomain Guy    void drawHardwareLayer(HardwareLayer layer, float x, float y, Paint paint) {
259a4e16c58c9e3c983251e0475125a2a6f5bec2dbfChris Craik        layer.setLayerPaint(paint);
2608dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nDrawLayer(mNativeCanvasWrapper, layer.getLayerHandle(), x, y);
2616c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    }
2626c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
26336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nDrawLayer(long renderer, long layer, float x, float y);
264aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy
2656c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    ///////////////////////////////////////////////////////////////////////////
266e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    // Drawing
267e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    ///////////////////////////////////////////////////////////////////////////
268e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
2698dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    // TODO: move to Canvas.java
270e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
271f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy    public void drawPatch(NinePatch patch, Rect dst, Paint paint) {
272f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy        Bitmap bitmap = patch.getBitmap();
2731abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik        throwIfCannotDraw(bitmap);
274dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger        final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
2757c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck        nDrawPatch(mNativeCanvasWrapper, bitmap, patch.mNativeChunk,
27676d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger                dst.left, dst.top, dst.right, dst.bottom, nativePaint);
277f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy    }
278f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy
2798dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    // TODO: move to Canvas.java
280f3187b7df158d2de36955ddcc666ba4b8544a2ceRomain Guy    @Override
2813b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public void drawPatch(NinePatch patch, RectF dst, Paint paint) {
2823b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        Bitmap bitmap = patch.getBitmap();
2831abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik        throwIfCannotDraw(bitmap);
284dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger        final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
2857c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck        nDrawPatch(mNativeCanvasWrapper, bitmap, patch.mNativeChunk,
28676d3a1b8d035d27bc80b0f2fc480a903bd001514Derek Sollenberger                dst.left, dst.top, dst.right, dst.bottom, nativePaint);
287deba785f122a47915756ffd991f5540d952cf937Romain Guy    }
288deba785f122a47915756ffd991f5540d952cf937Romain Guy
2897c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck    private static native void nDrawPatch(long renderer, Bitmap bitmap, long chunk,
29036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat            float left, float top, float right, float bottom, long paint);
291deba785f122a47915756ffd991f5540d952cf937Romain Guy
29252244fff29042926e21fa897ef5ab11148e35299John Reck    public void drawCircle(CanvasProperty<Float> cx, CanvasProperty<Float> cy,
29352244fff29042926e21fa897ef5ab11148e35299John Reck            CanvasProperty<Float> radius, CanvasProperty<Paint> paint) {
2948dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nDrawCircle(mNativeCanvasWrapper, cx.getNativeContainer(), cy.getNativeContainer(),
29552244fff29042926e21fa897ef5ab11148e35299John Reck                radius.getNativeContainer(), paint.getNativeContainer());
29652244fff29042926e21fa897ef5ab11148e35299John Reck    }
29752244fff29042926e21fa897ef5ab11148e35299John Reck
29852244fff29042926e21fa897ef5ab11148e35299John Reck    private static native void nDrawCircle(long renderer, long propCx,
29952244fff29042926e21fa897ef5ab11148e35299John Reck            long propCy, long propRadius, long propPaint);
30052244fff29042926e21fa897ef5ab11148e35299John Reck
301072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi    public void drawRoundRect(CanvasProperty<Float> left, CanvasProperty<Float> top,
302072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi            CanvasProperty<Float> right, CanvasProperty<Float> bottom, CanvasProperty<Float> rx,
303072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi            CanvasProperty<Float> ry, CanvasProperty<Paint> paint) {
3048dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        nDrawRoundRect(mNativeCanvasWrapper, left.getNativeContainer(), top.getNativeContainer(),
305072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi                right.getNativeContainer(), bottom.getNativeContainer(),
306072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi                rx.getNativeContainer(), ry.getNativeContainer(),
307072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi                paint.getNativeContainer());
308072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi    }
309072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi
310072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi    private static native void nDrawRoundRect(long renderer, long propLeft, long propTop,
311072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi            long propRight, long propBottom, long propRx, long propRy, long propPaint);
312072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi
3138dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    // TODO: move this optimization to Canvas.java
314e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    @Override
315e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    public void drawPath(Path path, Paint paint) {
316d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III        if (path.isSimplePath) {
317d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III            if (path.rects != null) {
3188dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson                nDrawRects(mNativeCanvasWrapper, path.rects.mNativeRegion, paint.getNativeInstance());
319a48a1a87ba17f20f7006eaab21dcedf86c015c13Romain Guy            }
320d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III        } else {
3218dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            super.drawPath(path, paint);
322a48a1a87ba17f20f7006eaab21dcedf86c015c13Romain Guy        }
323e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    }
324e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
32536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nDrawRects(long renderer, long region, long paint);
326e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy}
327