blob: 667fab5537c958c03a0493858f9294cbc5f8f670 [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;
John Reck4afbed12016-04-18 09:29:36 -070020import android.annotation.Nullable;
Mathew Inwooda570dee2018-08-17 14:56:00 +010021import android.annotation.UnsupportedAppUsage;
John Reck6b164402018-09-24 15:25:42 -070022import android.graphics.BaseRecordingCanvas;
Romain Guye4d01122010-06-16 18:44:05 -070023import android.graphics.Bitmap;
John Reck52244ff2014-05-01 21:27:37 -070024import android.graphics.CanvasProperty;
Romain Guye4d01122010-06-16 18:44:05 -070025import android.graphics.Paint;
Chris Craikc9070eb2015-03-09 18:50:14 -070026import android.util.Pools.SynchronizedPool;
Romain Guye4d01122010-06-16 18:44:05 -070027
Chris Craikfc294242016-12-13 18:10:46 -080028import dalvik.annotation.optimization.CriticalNative;
John Reck5cb74bc2016-10-07 11:24:44 -070029import dalvik.annotation.optimization.FastNative;
30
Romain Guye4d01122010-06-16 18:44:05 -070031/**
Derek Sollenbergerf64c34e2016-06-28 16:39:13 -040032 * A Canvas implementation that records view system drawing operations for deferred rendering.
Chris Craikc9070eb2015-03-09 18:50:14 -070033 * 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 */
John Reck6b164402018-09-24 15:25:42 -070039public final class DisplayListCanvas extends BaseRecordingCanvas {
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
Lucas Dupind8e12442018-08-21 09:20:48 -070044 public static final int MAX_BITMAP_SIZE = 100 * 1024 * 1024; // 100 MB
sergeyv3d8298e2016-04-21 13:05:24 -070045
Chris Craikc9070eb2015-03-09 18:50:14 -070046 private static final SynchronizedPool<DisplayListCanvas> sPool =
John Reckcaa08ff2016-10-07 13:21:36 -070047 new SynchronizedPool<>(POOL_LIMIT);
Chris Craikc9070eb2015-03-09 18:50:14 -070048
49 RenderNode mNode;
Romain Guye4d01122010-06-16 18:44:05 -070050 private int mWidth;
51 private int mHeight;
Raph Levien051910b2014-06-15 18:25:29 -070052
Derek Sollenbergercc882b62015-07-09 15:51:20 -040053 static DisplayListCanvas obtain(@NonNull RenderNode node, int width, int height) {
Chris Craikc9070eb2015-03-09 18:50:14 -070054 if (node == null) throw new IllegalArgumentException("node cannot be null");
55 DisplayListCanvas canvas = sPool.acquire();
56 if (canvas == null) {
Stan Ilievc0e7a902016-10-13 17:07:09 -040057 canvas = new DisplayListCanvas(node, width, height);
Derek Sollenbergercc882b62015-07-09 15:51:20 -040058 } else {
Stan Ilievc0e7a902016-10-13 17:07:09 -040059 nResetDisplayListCanvas(canvas.mNativeCanvasWrapper, node.mNativeRenderNode,
60 width, height);
Chris Craikc9070eb2015-03-09 18:50:14 -070061 }
62 canvas.mNode = node;
Derek Sollenbergercc882b62015-07-09 15:51:20 -040063 canvas.mWidth = width;
64 canvas.mHeight = height;
Chris Craikc9070eb2015-03-09 18:50:14 -070065 return canvas;
66 }
67
68 void recycle() {
69 mNode = null;
70 sPool.release(this);
71 }
72
73 long finishRecording() {
74 return nFinishRecording(mNativeCanvasWrapper);
75 }
76
77 @Override
78 public boolean isRecordingFor(Object o) {
79 return o == mNode;
80 }
Romain Guy6926c722010-07-12 20:20:03 -070081
Romain Guy16393512010-08-08 00:14:31 -070082 ///////////////////////////////////////////////////////////////////////////
Romain Guye4d01122010-06-16 18:44:05 -070083 // Constructors
84 ///////////////////////////////////////////////////////////////////////////
Romain Guyb051e892010-09-28 19:09:36 -070085
Stan Ilievc0e7a902016-10-13 17:07:09 -040086 private DisplayListCanvas(@NonNull RenderNode node, int width, int height) {
87 super(nCreateDisplayListCanvas(node.mNativeRenderNode, width, height));
Chris Craik9c08ee02015-05-21 16:46:53 -070088 mDensity = 0; // disable bitmap density scaling
Romain Guye4d01122010-06-16 18:44:05 -070089 }
Romain Guye4d01122010-06-16 18:44:05 -070090
Romain Guye4d01122010-06-16 18:44:05 -070091 ///////////////////////////////////////////////////////////////////////////
92 // Canvas management
93 ///////////////////////////////////////////////////////////////////////////
Romain Guye4d01122010-06-16 18:44:05 -070094
Chris Craik9c08ee02015-05-21 16:46:53 -070095
96 @Override
97 public void setDensity(int density) {
98 // drop silently, since DisplayListCanvas doesn't perform density scaling
99 }
100
Romain Guye4d01122010-06-16 18:44:05 -0700101 @Override
Chris Craikf6829a02015-03-10 10:28:59 -0700102 public boolean isHardwareAccelerated() {
103 return true;
104 }
105
106 @Override
107 public void setBitmap(Bitmap bitmap) {
108 throw new UnsupportedOperationException();
109 }
110
111 @Override
Romain Guye4d01122010-06-16 18:44:05 -0700112 public boolean isOpaque() {
Tom Hudson8dfaa492014-12-09 15:03:44 -0500113 return false;
Romain Guye4d01122010-06-16 18:44:05 -0700114 }
115
116 @Override
117 public int getWidth() {
118 return mWidth;
119 }
120
121 @Override
122 public int getHeight() {
123 return mHeight;
124 }
125
Romain Guyf61970fc2011-07-07 14:10:06 -0700126 @Override
127 public int getMaximumBitmapWidth() {
128 return nGetMaximumTextureWidth();
129 }
130
131 @Override
132 public int getMaximumBitmapHeight() {
133 return nGetMaximumTextureHeight();
134 }
135
Romain Guye4d01122010-06-16 18:44:05 -0700136 ///////////////////////////////////////////////////////////////////////////
137 // Setup
138 ///////////////////////////////////////////////////////////////////////////
139
140 @Override
Chris Craik8afd0f22014-08-21 17:41:57 -0700141 public void insertReorderBarrier() {
Tom Hudson8dfaa492014-12-09 15:03:44 -0500142 nInsertReorderBarrier(mNativeCanvasWrapper, true);
Chris Craik8afd0f22014-08-21 17:41:57 -0700143 }
144
145 @Override
146 public void insertInorderBarrier() {
Tom Hudson8dfaa492014-12-09 15:03:44 -0500147 nInsertReorderBarrier(mNativeCanvasWrapper, false);
Chris Craik8afd0f22014-08-21 17:41:57 -0700148 }
149
Romain Guy530041d2012-01-25 18:56:29 -0800150 ///////////////////////////////////////////////////////////////////////////
151 // Functor
152 ///////////////////////////////////////////////////////////////////////////
153
Chris Craikf6829a02015-03-10 10:28:59 -0700154 /**
John Reckcd1c3eb2016-04-14 10:38:54 -0700155 * Records the functor specified with the drawGLFunction function pointer. This is
156 * functionality used by webview for calling into their renderer from our display lists.
Chris Craikf6829a02015-03-10 10:28:59 -0700157 *
158 * @param drawGLFunction A native function pointer
159 */
Mathew Inwooda570dee2018-08-17 14:56:00 +0100160 @UnsupportedAppUsage
Narayan Kamath57616d3e2014-11-21 11:57:07 +0000161 public void callDrawGLFunction2(long drawGLFunction) {
John Reckcd1c3eb2016-04-14 10:38:54 -0700162 nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunction, null);
Chet Haasedaf98e92011-01-10 14:10:36 -0800163 }
164
John Reckcd1c3eb2016-04-14 10:38:54 -0700165 /**
166 * Records the functor specified with the drawGLFunction function pointer. This is
167 * functionality used by webview for calling into their renderer from our display lists.
168 *
169 * @param drawGLFunction A native function pointer
170 * @param releasedCallback Called when the display list is destroyed, and thus
171 * the functor is no longer referenced by this canvas's display list.
172 *
173 * NOTE: The callback does *not* necessarily mean that there are no longer
174 * any references to the functor, just that the reference from this specific
175 * canvas's display list has been released.
176 */
Mathew Inwooda570dee2018-08-17 14:56:00 +0100177 @UnsupportedAppUsage
John Reck4afbed12016-04-18 09:29:36 -0700178 public void drawGLFunctor2(long drawGLFunctor, @Nullable Runnable releasedCallback) {
John Reckcd1c3eb2016-04-14 10:38:54 -0700179 nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunctor, releasedCallback);
180 }
181
Romain Guybdf76092011-07-18 15:00:43 -0700182 ///////////////////////////////////////////////////////////////////////////
Romain Guyb051e892010-09-28 19:09:36 -0700183 // Display list
184 ///////////////////////////////////////////////////////////////////////////
185
Chris Craikf6829a02015-03-10 10:28:59 -0700186 /**
John Reck568b2a62018-06-04 17:02:02 -0700187 * Draws the specified display list onto this canvas.
Chris Craikf6829a02015-03-10 10:28:59 -0700188 *
Chris Craik956f3402015-04-27 16:41:00 -0700189 * @param renderNode The RenderNode to draw.
Chris Craikf6829a02015-03-10 10:28:59 -0700190 */
Mathew Inwooda570dee2018-08-17 14:56:00 +0100191 @UnsupportedAppUsage
Chris Craikf6829a02015-03-10 10:28:59 -0700192 public void drawRenderNode(RenderNode renderNode) {
John Reck568b2a62018-06-04 17:02:02 -0700193 nDrawRenderNode(mNativeCanvasWrapper, renderNode.mNativeRenderNode);
Chris Craikf6829a02015-03-10 10:28:59 -0700194 }
195
Romain Guye4d01122010-06-16 18:44:05 -0700196 ///////////////////////////////////////////////////////////////////////////
Romain Guy6c319ca2011-01-11 14:29:25 -0800197 // Hardware layer
198 ///////////////////////////////////////////////////////////////////////////
Raph Levien051910b2014-06-15 18:25:29 -0700199
Chris Craikf6829a02015-03-10 10:28:59 -0700200 /**
201 * Draws the specified layer onto this canvas.
202 *
203 * @param layer The layer to composite on this canvas
Chris Craikf6829a02015-03-10 10:28:59 -0700204 */
John Reck9d8d99d2018-02-21 12:55:41 -0800205 void drawTextureLayer(TextureLayer layer) {
206 nDrawTextureLayer(mNativeCanvasWrapper, layer.getLayerHandle());
Romain Guy6c319ca2011-01-11 14:29:25 -0800207 }
208
Romain Guy6c319ca2011-01-11 14:29:25 -0800209 ///////////////////////////////////////////////////////////////////////////
Romain Guye4d01122010-06-16 18:44:05 -0700210 // Drawing
211 ///////////////////////////////////////////////////////////////////////////
212
Mathew Inwooda570dee2018-08-17 14:56:00 +0100213 @UnsupportedAppUsage
John Reck52244ff2014-05-01 21:27:37 -0700214 public void drawCircle(CanvasProperty<Float> cx, CanvasProperty<Float> cy,
215 CanvasProperty<Float> radius, CanvasProperty<Paint> paint) {
Tom Hudson8dfaa492014-12-09 15:03:44 -0500216 nDrawCircle(mNativeCanvasWrapper, cx.getNativeContainer(), cy.getNativeContainer(),
John Reck52244ff2014-05-01 21:27:37 -0700217 radius.getNativeContainer(), paint.getNativeContainer());
218 }
219
Jorim Jaggi072707d2014-09-15 17:20:08 +0200220 public void drawRoundRect(CanvasProperty<Float> left, CanvasProperty<Float> top,
221 CanvasProperty<Float> right, CanvasProperty<Float> bottom, CanvasProperty<Float> rx,
222 CanvasProperty<Float> ry, CanvasProperty<Paint> paint) {
Tom Hudson8dfaa492014-12-09 15:03:44 -0500223 nDrawRoundRect(mNativeCanvasWrapper, left.getNativeContainer(), top.getNativeContainer(),
Jorim Jaggi072707d2014-09-15 17:20:08 +0200224 right.getNativeContainer(), bottom.getNativeContainer(),
225 rx.getNativeContainer(), ry.getNativeContainer(),
226 paint.getNativeContainer());
227 }
228
sergeyv3d8298e2016-04-21 13:05:24 -0700229 @Override
230 protected void throwIfCannotDraw(Bitmap bitmap) {
231 super.throwIfCannotDraw(bitmap);
232 int bitmapSize = bitmap.getByteCount();
233 if (bitmapSize > MAX_BITMAP_SIZE) {
234 throw new RuntimeException(
235 "Canvas: trying to draw too large(" + bitmapSize + "bytes) bitmap.");
236 }
237 }
John Reck5cb74bc2016-10-07 11:24:44 -0700238
Chris Craikfc294242016-12-13 18:10:46 -0800239
240 // ------------------ Fast JNI ------------------------
241
John Reck5cb74bc2016-10-07 11:24:44 -0700242 @FastNative
243 private static native void nCallDrawGLFunction(long renderer,
244 long drawGLFunction, Runnable releasedCallback);
Chris Craikfc294242016-12-13 18:10:46 -0800245
246
247 // ------------------ Critical JNI ------------------------
248
249 @CriticalNative
250 private static native long nCreateDisplayListCanvas(long node, int width, int height);
251 @CriticalNative
252 private static native void nResetDisplayListCanvas(long canvas, long node,
253 int width, int height);
254 @CriticalNative
255 private static native int nGetMaximumTextureWidth();
256 @CriticalNative
257 private static native int nGetMaximumTextureHeight();
258 @CriticalNative
259 private static native void nInsertReorderBarrier(long renderer, boolean enableReorder);
260 @CriticalNative
John Reck5cb74bc2016-10-07 11:24:44 -0700261 private static native long nFinishRecording(long renderer);
Chris Craikfc294242016-12-13 18:10:46 -0800262 @CriticalNative
John Reck5cb74bc2016-10-07 11:24:44 -0700263 private static native void nDrawRenderNode(long renderer, long renderNode);
Chris Craikfc294242016-12-13 18:10:46 -0800264 @CriticalNative
John Reck9d8d99d2018-02-21 12:55:41 -0800265 private static native void nDrawTextureLayer(long renderer, long layer);
Chris Craikfc294242016-12-13 18:10:46 -0800266 @CriticalNative
John Reck5cb74bc2016-10-07 11:24:44 -0700267 private static native void nDrawCircle(long renderer, long propCx,
268 long propCy, long propRadius, long propPaint);
Chris Craikfc294242016-12-13 18:10:46 -0800269 @CriticalNative
John Reck5cb74bc2016-10-07 11:24:44 -0700270 private static native void nDrawRoundRect(long renderer, long propLeft, long propTop,
271 long propRight, long propBottom, long propRx, long propRy, long propPaint);
Romain Guye4d01122010-06-16 18:44:05 -0700272}