blob: 05fa45fc3ff21589c6ab6219993ea8c7478cddc6 [file] [log] [blame]
Romain Guye4d01122010-06-16 18:44:05 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.view;
18
Chris Craikc9070eb2015-03-09 18:50:14 -070019import android.annotation.NonNull;
Romain Guye4d01122010-06-16 18:44:05 -070020import android.graphics.Bitmap;
Chris Craikf6829a02015-03-10 10:28:59 -070021import android.graphics.Canvas;
John Reck52244ff2014-05-01 21:27:37 -070022import android.graphics.CanvasProperty;
Romain Guy3b748a42013-04-17 18:54:38 -070023import android.graphics.NinePatch;
Romain Guye4d01122010-06-16 18:44:05 -070024import android.graphics.Paint;
25import android.graphics.Path;
26import android.graphics.Picture;
Romain Guye4d01122010-06-16 18:44:05 -070027import android.graphics.Rect;
28import android.graphics.RectF;
Chris Craikc9070eb2015-03-09 18:50:14 -070029import android.util.Pools.SynchronizedPool;
Romain Guye4d01122010-06-16 18:44:05 -070030
Romain Guye4d01122010-06-16 18:44:05 -070031/**
Chris Craikc9070eb2015-03-09 18:50:14 -070032 * An implementation of a GL canvas that records drawing operations.
33 * This is intended for use with a DisplayList. This class keeps a list of all the Paint and
34 * Bitmap objects that it draws, preventing the backing memory of Bitmaps from being freed while
35 * the DisplayList is still holding a native reference to the memory.
Chris Craikf6829a02015-03-10 10:28:59 -070036 *
37 * @hide
Romain Guye4d01122010-06-16 18:44:05 -070038 */
Chris Craikf6829a02015-03-10 10:28:59 -070039public class DisplayListCanvas extends Canvas {
Chris Craikc9070eb2015-03-09 18:50:14 -070040 // The recording canvas pool should be large enough to handle a deeply nested
41 // view hierarchy because display lists are generated recursively.
42 private static final int POOL_LIMIT = 25;
43
44 private static final SynchronizedPool<DisplayListCanvas> sPool =
45 new SynchronizedPool<DisplayListCanvas>(POOL_LIMIT);
46
47 RenderNode mNode;
Romain Guye4d01122010-06-16 18:44:05 -070048 private int mWidth;
49 private int mHeight;
Raph Levien051910b2014-06-15 18:25:29 -070050
Derek Sollenbergercc882b62015-07-09 15:51:20 -040051 static DisplayListCanvas obtain(@NonNull RenderNode node, int width, int height) {
Chris Craikc9070eb2015-03-09 18:50:14 -070052 if (node == null) throw new IllegalArgumentException("node cannot be null");
53 DisplayListCanvas canvas = sPool.acquire();
54 if (canvas == null) {
Derek Sollenbergercc882b62015-07-09 15:51:20 -040055 canvas = new DisplayListCanvas(width, height);
56 } else {
57 nResetDisplayListCanvas(canvas.mNativeCanvasWrapper, width, height);
Chris Craikc9070eb2015-03-09 18:50:14 -070058 }
59 canvas.mNode = node;
Derek Sollenbergercc882b62015-07-09 15:51:20 -040060 canvas.mWidth = width;
61 canvas.mHeight = height;
Chris Craikc9070eb2015-03-09 18:50:14 -070062 return canvas;
63 }
64
65 void recycle() {
66 mNode = null;
67 sPool.release(this);
68 }
69
70 long finishRecording() {
71 return nFinishRecording(mNativeCanvasWrapper);
72 }
73
74 @Override
75 public boolean isRecordingFor(Object o) {
76 return o == mNode;
77 }
Romain Guy6926c722010-07-12 20:20:03 -070078
Romain Guy16393512010-08-08 00:14:31 -070079 ///////////////////////////////////////////////////////////////////////////
80 // JNI
81 ///////////////////////////////////////////////////////////////////////////
82
83 private static native boolean nIsAvailable();
84 private static boolean sIsAvailable = nIsAvailable();
85
86 static boolean isAvailable() {
87 return sIsAvailable;
88 }
Romain Guye4d01122010-06-16 18:44:05 -070089
90 ///////////////////////////////////////////////////////////////////////////
91 // Constructors
92 ///////////////////////////////////////////////////////////////////////////
Romain Guyb051e892010-09-28 19:09:36 -070093
Derek Sollenbergercc882b62015-07-09 15:51:20 -040094 private DisplayListCanvas(int width, int height) {
95 super(nCreateDisplayListCanvas(width, height));
Chris Craik9c08ee02015-05-21 16:46:53 -070096 mDensity = 0; // disable bitmap density scaling
Romain Guye4d01122010-06-16 18:44:05 -070097 }
Romain Guye4d01122010-06-16 18:44:05 -070098
Derek Sollenbergercc882b62015-07-09 15:51:20 -040099 private static native long nCreateDisplayListCanvas(int width, int height);
100 private static native void nResetDisplayListCanvas(long canvas, int width, int height);
Romain Guyce0537b2010-06-29 21:05:21 -0700101
Romain Guye4d01122010-06-16 18:44:05 -0700102 ///////////////////////////////////////////////////////////////////////////
103 // Canvas management
104 ///////////////////////////////////////////////////////////////////////////
Romain Guye4d01122010-06-16 18:44:05 -0700105
Chris Craik9c08ee02015-05-21 16:46:53 -0700106
107 @Override
108 public void setDensity(int density) {
109 // drop silently, since DisplayListCanvas doesn't perform density scaling
110 }
111
Romain Guye4d01122010-06-16 18:44:05 -0700112 @Override
Chris Craikf6829a02015-03-10 10:28:59 -0700113 public boolean isHardwareAccelerated() {
114 return true;
115 }
116
117 @Override
118 public void setBitmap(Bitmap bitmap) {
119 throw new UnsupportedOperationException();
120 }
121
122 @Override
Romain Guye4d01122010-06-16 18:44:05 -0700123 public boolean isOpaque() {
Tom Hudson8dfaa492014-12-09 15:03:44 -0500124 return false;
Romain Guye4d01122010-06-16 18:44:05 -0700125 }
126
127 @Override
128 public int getWidth() {
129 return mWidth;
130 }
131
132 @Override
133 public int getHeight() {
134 return mHeight;
135 }
136
Romain Guyf61970fc2011-07-07 14:10:06 -0700137 @Override
138 public int getMaximumBitmapWidth() {
139 return nGetMaximumTextureWidth();
140 }
141
142 @Override
143 public int getMaximumBitmapHeight() {
144 return nGetMaximumTextureHeight();
145 }
146
147 private static native int nGetMaximumTextureWidth();
Romain Guy530041d2012-01-25 18:56:29 -0800148 private static native int nGetMaximumTextureHeight();
Romain Guyf61970fc2011-07-07 14:10:06 -0700149
Romain Guye4d01122010-06-16 18:44:05 -0700150 ///////////////////////////////////////////////////////////////////////////
151 // Setup
152 ///////////////////////////////////////////////////////////////////////////
153
154 @Override
Chris Craik8afd0f22014-08-21 17:41:57 -0700155 public void insertReorderBarrier() {
Tom Hudson8dfaa492014-12-09 15:03:44 -0500156 nInsertReorderBarrier(mNativeCanvasWrapper, true);
Chris Craik8afd0f22014-08-21 17:41:57 -0700157 }
158
159 @Override
160 public void insertInorderBarrier() {
Tom Hudson8dfaa492014-12-09 15:03:44 -0500161 nInsertReorderBarrier(mNativeCanvasWrapper, false);
Chris Craik8afd0f22014-08-21 17:41:57 -0700162 }
163
164 private static native void nInsertReorderBarrier(long renderer, boolean enableReorder);
165
Romain Guy530041d2012-01-25 18:56:29 -0800166 ///////////////////////////////////////////////////////////////////////////
167 // Functor
168 ///////////////////////////////////////////////////////////////////////////
169
Chris Craikf6829a02015-03-10 10:28:59 -0700170 /**
171 * Calls the function specified with the drawGLFunction function pointer. This is
172 * functionality used by webkit for calling into their renderer from our display lists.
173 * This function may return true if an invalidation is needed after the call.
174 *
175 * @param drawGLFunction A native function pointer
176 */
Narayan Kamath57616d3e2014-11-21 11:57:07 +0000177 public void callDrawGLFunction2(long drawGLFunction) {
Tom Hudson8dfaa492014-12-09 15:03:44 -0500178 nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunction);
Chet Haasedaf98e92011-01-10 14:10:36 -0800179 }
180
Tom Hudson107843d2014-09-08 11:26:26 -0400181 private static native void nCallDrawGLFunction(long renderer, long drawGLFunction);
Chet Haasedaf98e92011-01-10 14:10:36 -0800182
Romain Guybdf76092011-07-18 15:00:43 -0700183 ///////////////////////////////////////////////////////////////////////////
Romain Guyb051e892010-09-28 19:09:36 -0700184 // Display list
185 ///////////////////////////////////////////////////////////////////////////
186
John Reck44fd8d22014-02-26 11:00:11 -0800187 protected static native long nFinishRecording(long renderer);
Romain Guy52036b12013-02-14 18:03:37 -0800188
Chris Craikf6829a02015-03-10 10:28:59 -0700189 /**
190 * Draws the specified display list onto this canvas. The display list can only
191 * be drawn if {@link android.view.RenderNode#isValid()} returns true.
192 *
Chris Craik956f3402015-04-27 16:41:00 -0700193 * @param renderNode The RenderNode to draw.
Chris Craikf6829a02015-03-10 10:28:59 -0700194 */
195 public void drawRenderNode(RenderNode renderNode) {
Chris Craik956f3402015-04-27 16:41:00 -0700196 nDrawRenderNode(mNativeCanvasWrapper, renderNode.getNativeDisplayList());
Chris Craikf6829a02015-03-10 10:28:59 -0700197 }
198
Chris Craik956f3402015-04-27 16:41:00 -0700199 private static native void nDrawRenderNode(long renderer, long renderNode);
Romain Guyda8532c2010-08-31 11:50:35 -0700200
Romain Guye4d01122010-06-16 18:44:05 -0700201 ///////////////////////////////////////////////////////////////////////////
Romain Guy6c319ca2011-01-11 14:29:25 -0800202 // Hardware layer
203 ///////////////////////////////////////////////////////////////////////////
Raph Levien051910b2014-06-15 18:25:29 -0700204
Chris Craikf6829a02015-03-10 10:28:59 -0700205 /**
206 * Draws the specified layer onto this canvas.
207 *
208 * @param layer The layer to composite on this canvas
209 * @param x The left coordinate of the layer
210 * @param y The top coordinate of the layer
211 * @param paint The paint used to draw the layer
212 */
Romain Guyada830f2011-01-13 12:13:20 -0800213 void drawHardwareLayer(HardwareLayer layer, float x, float y, Paint paint) {
Chris Craika4e16c52013-03-22 10:00:48 -0700214 layer.setLayerPaint(paint);
Tom Hudson8dfaa492014-12-09 15:03:44 -0500215 nDrawLayer(mNativeCanvasWrapper, layer.getLayerHandle(), x, y);
Romain Guy6c319ca2011-01-11 14:29:25 -0800216 }
217
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000218 private static native void nDrawLayer(long renderer, long layer, float x, float y);
Romain Guyaa6c24c2011-04-28 18:40:04 -0700219
Romain Guy6c319ca2011-01-11 14:29:25 -0800220 ///////////////////////////////////////////////////////////////////////////
Romain Guye4d01122010-06-16 18:44:05 -0700221 // Drawing
222 ///////////////////////////////////////////////////////////////////////////
223
John Reck773bbe02015-08-17 15:18:29 -0700224 // TODO: move to Canvas.java
225 @Override
226 public void drawPatch(NinePatch patch, Rect dst, Paint paint) {
227 Bitmap bitmap = patch.getBitmap();
228 throwIfCannotDraw(bitmap);
229 final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
230 nDrawPatch(mNativeCanvasWrapper, bitmap, patch.mNativeChunk,
231 dst.left, dst.top, dst.right, dst.bottom, nativePaint);
232 }
233
234 // TODO: move to Canvas.java
235 @Override
236 public void drawPatch(NinePatch patch, RectF dst, Paint paint) {
237 Bitmap bitmap = patch.getBitmap();
238 throwIfCannotDraw(bitmap);
239 final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
240 nDrawPatch(mNativeCanvasWrapper, bitmap, patch.mNativeChunk,
241 dst.left, dst.top, dst.right, dst.bottom, nativePaint);
242 }
243
244 private static native void nDrawPatch(long renderer, Bitmap bitmap, long chunk,
245 float left, float top, float right, float bottom, long paint);
246
John Reck52244ff2014-05-01 21:27:37 -0700247 public void drawCircle(CanvasProperty<Float> cx, CanvasProperty<Float> cy,
248 CanvasProperty<Float> radius, CanvasProperty<Paint> paint) {
Tom Hudson8dfaa492014-12-09 15:03:44 -0500249 nDrawCircle(mNativeCanvasWrapper, cx.getNativeContainer(), cy.getNativeContainer(),
John Reck52244ff2014-05-01 21:27:37 -0700250 radius.getNativeContainer(), paint.getNativeContainer());
251 }
252
253 private static native void nDrawCircle(long renderer, long propCx,
254 long propCy, long propRadius, long propPaint);
255
Jorim Jaggi072707d2014-09-15 17:20:08 +0200256 public void drawRoundRect(CanvasProperty<Float> left, CanvasProperty<Float> top,
257 CanvasProperty<Float> right, CanvasProperty<Float> bottom, CanvasProperty<Float> rx,
258 CanvasProperty<Float> ry, CanvasProperty<Paint> paint) {
Tom Hudson8dfaa492014-12-09 15:03:44 -0500259 nDrawRoundRect(mNativeCanvasWrapper, left.getNativeContainer(), top.getNativeContainer(),
Jorim Jaggi072707d2014-09-15 17:20:08 +0200260 right.getNativeContainer(), bottom.getNativeContainer(),
261 rx.getNativeContainer(), ry.getNativeContainer(),
262 paint.getNativeContainer());
263 }
264
265 private static native void nDrawRoundRect(long renderer, long propLeft, long propTop,
266 long propRight, long propBottom, long propRx, long propRy, long propPaint);
Romain Guye4d01122010-06-16 18:44:05 -0700267}