Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2015 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 | |
Chris Craik | 5e00c7c | 2016-07-06 16:10:09 -0700 | [diff] [blame] | 17 | #pragma once |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 18 | |
Chris Craik | a171727 | 2015-11-19 13:02:43 -0800 | [diff] [blame] | 19 | #include "font/FontUtil.h" |
Greg Daniel | 8cd3edf | 2017-01-09 14:15:41 -0500 | [diff] [blame] | 20 | #include "GlLayer.h" |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 21 | #include "Matrix.h" |
Chris Craik | 98787e6 | 2015-11-13 10:55:30 -0800 | [diff] [blame] | 22 | #include "Rect.h" |
Chris Craik | 0b7e824 | 2015-10-28 16:50:44 -0700 | [diff] [blame] | 23 | #include "RenderNode.h" |
Chris Craik | 6e068c01 | 2016-01-15 16:15:30 -0800 | [diff] [blame] | 24 | #include "TessellationCache.h" |
Chris Craik | 98787e6 | 2015-11-13 10:55:30 -0800 | [diff] [blame] | 25 | #include "utils/LinearAllocator.h" |
Chris Craik | 5e00c7c | 2016-07-06 16:10:09 -0700 | [diff] [blame] | 26 | #include "utils/PaintUtils.h" |
Chris Craik | 98787e6 | 2015-11-13 10:55:30 -0800 | [diff] [blame] | 27 | #include "Vector.h" |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 28 | |
Chris Craik | f09ff5a | 2015-12-08 17:21:58 -0800 | [diff] [blame] | 29 | #include <androidfw/ResourceTypes.h> |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 30 | |
| 31 | class SkBitmap; |
| 32 | class SkPaint; |
| 33 | |
| 34 | namespace android { |
| 35 | namespace uirenderer { |
| 36 | |
Chris Craik | e4db79d | 2015-12-22 16:32:23 -0800 | [diff] [blame] | 37 | struct ClipBase; |
Chris Craik | 5854b34 | 2015-10-26 15:49:56 -0700 | [diff] [blame] | 38 | class OffscreenBuffer; |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 39 | class RenderNode; |
| 40 | struct Vertex; |
| 41 | |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 42 | namespace VectorDrawable { |
| 43 | class Tree; |
| 44 | } |
| 45 | |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 46 | /** |
Chris Craik | 7cbf63d | 2016-01-06 13:46:52 -0800 | [diff] [blame] | 47 | * Authoritative op list, used for generating the op ID enum, ID based LUTS, and |
| 48 | * the functions to which they dispatch. Parameter macros are executed for each op, |
| 49 | * in order, based on the op's type. |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 50 | * |
Chris Craik | b87eadd | 2016-01-06 09:16:05 -0800 | [diff] [blame] | 51 | * There are 4 types of op, which defines dispatch/LUT capability: |
Chris Craik | 7cbf63d | 2016-01-06 13:46:52 -0800 | [diff] [blame] | 52 | * |
Chris Craik | b87eadd | 2016-01-06 09:16:05 -0800 | [diff] [blame] | 53 | * | DisplayList | Render | Merge | |
| 54 | * -------------|-------------|-------------|-------------| |
| 55 | * PRE RENDER | Yes | | | |
| 56 | * RENDER ONLY | | Yes | | |
| 57 | * UNMERGEABLE | Yes | Yes | | |
| 58 | * MERGEABLE | Yes | Yes | Yes | |
| 59 | * |
| 60 | * PRE RENDER - These ops are recorded into DisplayLists, but can't be directly rendered. This |
| 61 | * may be because they need to be transformed into other op types (e.g. CirclePropsOp), |
| 62 | * be traversed to access multiple renderable ops within (e.g. RenderNodeOp), or because they |
| 63 | * modify renderbuffer lifecycle, instead of directly rendering content (the various LayerOps). |
| 64 | * |
| 65 | * RENDER ONLY - These ops cannot be recorded into DisplayLists, and are instead implicitly |
| 66 | * constructed from other commands/RenderNode properties. They cannot be merged. |
| 67 | * |
| 68 | * UNMERGEABLE - These ops can be recorded into DisplayLists and rendered directly, but do not |
| 69 | * support merged rendering. |
| 70 | * |
| 71 | * MERGEABLE - These ops can be recorded into DisplayLists and rendered individually, or merged |
| 72 | * under certain circumstances. |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 73 | */ |
Chris Craik | 7cbf63d | 2016-01-06 13:46:52 -0800 | [diff] [blame] | 74 | #define MAP_OPS_BASED_ON_TYPE(PRE_RENDER_OP_FN, RENDER_ONLY_OP_FN, UNMERGEABLE_OP_FN, MERGEABLE_OP_FN) \ |
| 75 | PRE_RENDER_OP_FN(RenderNodeOp) \ |
| 76 | PRE_RENDER_OP_FN(CirclePropsOp) \ |
| 77 | PRE_RENDER_OP_FN(RoundRectPropsOp) \ |
| 78 | PRE_RENDER_OP_FN(BeginLayerOp) \ |
| 79 | PRE_RENDER_OP_FN(EndLayerOp) \ |
Chris Craik | b87eadd | 2016-01-06 09:16:05 -0800 | [diff] [blame] | 80 | PRE_RENDER_OP_FN(BeginUnclippedLayerOp) \ |
| 81 | PRE_RENDER_OP_FN(EndUnclippedLayerOp) \ |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 82 | PRE_RENDER_OP_FN(VectorDrawableOp) \ |
Chris Craik | 7cbf63d | 2016-01-06 13:46:52 -0800 | [diff] [blame] | 83 | \ |
| 84 | RENDER_ONLY_OP_FN(ShadowOp) \ |
| 85 | RENDER_ONLY_OP_FN(LayerOp) \ |
Chris Craik | b87eadd | 2016-01-06 09:16:05 -0800 | [diff] [blame] | 86 | RENDER_ONLY_OP_FN(CopyToLayerOp) \ |
| 87 | RENDER_ONLY_OP_FN(CopyFromLayerOp) \ |
Chris Craik | 7cbf63d | 2016-01-06 13:46:52 -0800 | [diff] [blame] | 88 | \ |
| 89 | UNMERGEABLE_OP_FN(ArcOp) \ |
| 90 | UNMERGEABLE_OP_FN(BitmapMeshOp) \ |
| 91 | UNMERGEABLE_OP_FN(BitmapRectOp) \ |
Chris Craik | a204848 | 2016-03-25 14:17:49 -0700 | [diff] [blame] | 92 | UNMERGEABLE_OP_FN(ColorOp) \ |
Chris Craik | 7cbf63d | 2016-01-06 13:46:52 -0800 | [diff] [blame] | 93 | UNMERGEABLE_OP_FN(FunctorOp) \ |
| 94 | UNMERGEABLE_OP_FN(LinesOp) \ |
| 95 | UNMERGEABLE_OP_FN(OvalOp) \ |
| 96 | UNMERGEABLE_OP_FN(PathOp) \ |
| 97 | UNMERGEABLE_OP_FN(PointsOp) \ |
| 98 | UNMERGEABLE_OP_FN(RectOp) \ |
| 99 | UNMERGEABLE_OP_FN(RoundRectOp) \ |
| 100 | UNMERGEABLE_OP_FN(SimpleRectsOp) \ |
| 101 | UNMERGEABLE_OP_FN(TextOnPathOp) \ |
| 102 | UNMERGEABLE_OP_FN(TextureLayerOp) \ |
| 103 | \ |
| 104 | MERGEABLE_OP_FN(BitmapOp) \ |
| 105 | MERGEABLE_OP_FN(PatchOp) \ |
| 106 | MERGEABLE_OP_FN(TextOp) |
Chris Craik | 15c3f19 | 2015-12-03 12:16:56 -0800 | [diff] [blame] | 107 | |
| 108 | /** |
Chris Craik | 7cbf63d | 2016-01-06 13:46:52 -0800 | [diff] [blame] | 109 | * LUT generators, which will insert nullptr for unsupported ops |
Chris Craik | 15c3f19 | 2015-12-03 12:16:56 -0800 | [diff] [blame] | 110 | */ |
Chris Craik | 7cbf63d | 2016-01-06 13:46:52 -0800 | [diff] [blame] | 111 | #define NULLPTR_OP_FN(Type) nullptr, |
Chris Craik | 15c3f19 | 2015-12-03 12:16:56 -0800 | [diff] [blame] | 112 | |
Chris Craik | 7cbf63d | 2016-01-06 13:46:52 -0800 | [diff] [blame] | 113 | #define BUILD_DEFERRABLE_OP_LUT(OP_FN) \ |
| 114 | { MAP_OPS_BASED_ON_TYPE(OP_FN, NULLPTR_OP_FN, OP_FN, OP_FN) } |
| 115 | |
| 116 | #define BUILD_MERGEABLE_OP_LUT(OP_FN) \ |
| 117 | { MAP_OPS_BASED_ON_TYPE(NULLPTR_OP_FN, NULLPTR_OP_FN, NULLPTR_OP_FN, OP_FN) } |
| 118 | |
| 119 | #define BUILD_RENDERABLE_OP_LUT(OP_FN) \ |
| 120 | { MAP_OPS_BASED_ON_TYPE(NULLPTR_OP_FN, OP_FN, OP_FN, OP_FN) } |
| 121 | |
Chris Craik | 91eff22 | 2016-02-22 13:39:33 -0800 | [diff] [blame] | 122 | #define BUILD_FULL_OP_LUT(OP_FN) \ |
| 123 | { MAP_OPS_BASED_ON_TYPE(OP_FN, OP_FN, OP_FN, OP_FN) } |
| 124 | |
Chris Craik | 7cbf63d | 2016-01-06 13:46:52 -0800 | [diff] [blame] | 125 | /** |
| 126 | * Op mapping functions, which skip unsupported ops. |
| 127 | * |
| 128 | * Note: Do not use for LUTS, since these do not preserve ID order. |
| 129 | */ |
Chris Craik | 15c3f19 | 2015-12-03 12:16:56 -0800 | [diff] [blame] | 130 | #define NULL_OP_FN(Type) |
| 131 | |
Chris Craik | b87eadd | 2016-01-06 09:16:05 -0800 | [diff] [blame] | 132 | #define MAP_DEFERRABLE_OPS(OP_FN) \ |
| 133 | MAP_OPS_BASED_ON_TYPE(OP_FN, NULL_OP_FN, OP_FN, OP_FN) |
| 134 | |
Chris Craik | 7cbf63d | 2016-01-06 13:46:52 -0800 | [diff] [blame] | 135 | #define MAP_MERGEABLE_OPS(OP_FN) \ |
| 136 | MAP_OPS_BASED_ON_TYPE(NULL_OP_FN, NULL_OP_FN, NULL_OP_FN, OP_FN) |
| 137 | |
| 138 | #define MAP_RENDERABLE_OPS(OP_FN) \ |
| 139 | MAP_OPS_BASED_ON_TYPE(NULL_OP_FN, OP_FN, OP_FN, OP_FN) |
| 140 | |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 141 | // Generate OpId enum |
| 142 | #define IDENTITY_FN(Type) Type, |
| 143 | namespace RecordedOpId { |
| 144 | enum { |
Chris Craik | 7cbf63d | 2016-01-06 13:46:52 -0800 | [diff] [blame] | 145 | MAP_OPS_BASED_ON_TYPE(IDENTITY_FN, IDENTITY_FN, IDENTITY_FN, IDENTITY_FN) |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 146 | Count, |
| 147 | }; |
| 148 | } |
Chris Craik | 7cbf63d | 2016-01-06 13:46:52 -0800 | [diff] [blame] | 149 | static_assert(RecordedOpId::RenderNodeOp == 0, |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 150 | "First index must be zero for LUTs to work"); |
| 151 | |
Chris Craik | e4db79d | 2015-12-22 16:32:23 -0800 | [diff] [blame] | 152 | #define BASE_PARAMS const Rect& unmappedBounds, const Matrix4& localMatrix, const ClipBase* localClip, const SkPaint* paint |
| 153 | #define BASE_PARAMS_PAINTLESS const Rect& unmappedBounds, const Matrix4& localMatrix, const ClipBase* localClip |
| 154 | #define SUPER(Type) RecordedOp(RecordedOpId::Type, unmappedBounds, localMatrix, localClip, paint) |
| 155 | #define SUPER_PAINTLESS(Type) RecordedOp(RecordedOpId::Type, unmappedBounds, localMatrix, localClip, nullptr) |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 156 | |
| 157 | struct RecordedOp { |
| 158 | /* ID from RecordedOpId - generally used for jumping into function tables */ |
| 159 | const int opId; |
| 160 | |
Chris Craik | 386aa03 | 2015-12-07 17:08:25 -0800 | [diff] [blame] | 161 | /* bounds in *local* space, without accounting for DisplayList transformation, or stroke */ |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 162 | const Rect unmappedBounds; |
| 163 | |
| 164 | /* transform in recording space (vs DisplayList origin) */ |
| 165 | const Matrix4 localMatrix; |
| 166 | |
Chris Craik | e4db79d | 2015-12-22 16:32:23 -0800 | [diff] [blame] | 167 | /* clip in recording space - nullptr if not clipped */ |
| 168 | const ClipBase* localClip; |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 169 | |
| 170 | /* optional paint, stored in base object to simplify merging logic */ |
| 171 | const SkPaint* paint; |
| 172 | protected: |
| 173 | RecordedOp(unsigned int opId, BASE_PARAMS) |
| 174 | : opId(opId) |
| 175 | , unmappedBounds(unmappedBounds) |
| 176 | , localMatrix(localMatrix) |
Chris Craik | e4db79d | 2015-12-22 16:32:23 -0800 | [diff] [blame] | 177 | , localClip(localClip) |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 178 | , paint(paint) {} |
| 179 | }; |
| 180 | |
| 181 | struct RenderNodeOp : RecordedOp { |
| 182 | RenderNodeOp(BASE_PARAMS_PAINTLESS, RenderNode* renderNode) |
| 183 | : SUPER_PAINTLESS(RenderNodeOp) |
| 184 | , renderNode(renderNode) {} |
Chris Craik | 8d1f212 | 2015-11-24 16:40:09 -0800 | [diff] [blame] | 185 | RenderNode * renderNode; // not const, since drawing modifies it |
| 186 | |
| 187 | /** |
| 188 | * Holds the transformation between the projection surface ViewGroup and this RenderNode |
| 189 | * drawing instance. Represents any translations / transformations done within the drawing of |
| 190 | * the compositing ancestor ViewGroup's draw, before the draw of the View represented by this |
| 191 | * DisplayList draw instance. |
| 192 | * |
| 193 | * Note: doesn't include transformation within the RenderNode, or its properties. |
| 194 | */ |
| 195 | Matrix4 transformFromCompositingAncestor; |
Chris Craik | 161f54b | 2015-11-05 11:08:52 -0800 | [diff] [blame] | 196 | bool skipInOrderDraw = false; |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 197 | }; |
| 198 | |
Chris Craik | a171727 | 2015-11-19 13:02:43 -0800 | [diff] [blame] | 199 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 200 | // Standard Ops |
| 201 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 202 | |
Chris Craik | 386aa03 | 2015-12-07 17:08:25 -0800 | [diff] [blame] | 203 | struct ArcOp : RecordedOp { |
| 204 | ArcOp(BASE_PARAMS, float startAngle, float sweepAngle, bool useCenter) |
| 205 | : SUPER(ArcOp) |
| 206 | , startAngle(startAngle) |
| 207 | , sweepAngle(sweepAngle) |
| 208 | , useCenter(useCenter) {} |
| 209 | const float startAngle; |
| 210 | const float sweepAngle; |
| 211 | const bool useCenter; |
| 212 | }; |
| 213 | |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 214 | struct BitmapOp : RecordedOp { |
sergeyv | ec4a4b1 | 2016-10-20 18:39:04 -0700 | [diff] [blame] | 215 | BitmapOp(BASE_PARAMS, Bitmap* bitmap) |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 216 | : SUPER(BitmapOp) |
| 217 | , bitmap(bitmap) {} |
sergeyv | ec4a4b1 | 2016-10-20 18:39:04 -0700 | [diff] [blame] | 218 | Bitmap* bitmap; |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 219 | }; |
| 220 | |
Chris Craik | f09ff5a | 2015-12-08 17:21:58 -0800 | [diff] [blame] | 221 | struct BitmapMeshOp : RecordedOp { |
sergeyv | ec4a4b1 | 2016-10-20 18:39:04 -0700 | [diff] [blame] | 222 | BitmapMeshOp(BASE_PARAMS, Bitmap* bitmap, int meshWidth, int meshHeight, |
Chris Craik | f09ff5a | 2015-12-08 17:21:58 -0800 | [diff] [blame] | 223 | const float* vertices, const int* colors) |
| 224 | : SUPER(BitmapMeshOp) |
| 225 | , bitmap(bitmap) |
| 226 | , meshWidth(meshWidth) |
| 227 | , meshHeight(meshHeight) |
| 228 | , vertices(vertices) |
| 229 | , colors(colors) {} |
sergeyv | ec4a4b1 | 2016-10-20 18:39:04 -0700 | [diff] [blame] | 230 | Bitmap* bitmap; |
Chris Craik | f09ff5a | 2015-12-08 17:21:58 -0800 | [diff] [blame] | 231 | const int meshWidth; |
| 232 | const int meshHeight; |
| 233 | const float* vertices; |
| 234 | const int* colors; |
| 235 | }; |
| 236 | |
| 237 | struct BitmapRectOp : RecordedOp { |
sergeyv | ec4a4b1 | 2016-10-20 18:39:04 -0700 | [diff] [blame] | 238 | BitmapRectOp(BASE_PARAMS, Bitmap* bitmap, const Rect& src) |
Chris Craik | f09ff5a | 2015-12-08 17:21:58 -0800 | [diff] [blame] | 239 | : SUPER(BitmapRectOp) |
| 240 | , bitmap(bitmap) |
| 241 | , src(src) {} |
sergeyv | ec4a4b1 | 2016-10-20 18:39:04 -0700 | [diff] [blame] | 242 | Bitmap* bitmap; |
Chris Craik | f09ff5a | 2015-12-08 17:21:58 -0800 | [diff] [blame] | 243 | const Rect src; |
| 244 | }; |
| 245 | |
Chris Craik | 268a9c0 | 2015-12-09 18:05:12 -0800 | [diff] [blame] | 246 | struct CirclePropsOp : RecordedOp { |
Chris Craik | e4db79d | 2015-12-22 16:32:23 -0800 | [diff] [blame] | 247 | CirclePropsOp(const Matrix4& localMatrix, const ClipBase* localClip, const SkPaint* paint, |
Chris Craik | 268a9c0 | 2015-12-09 18:05:12 -0800 | [diff] [blame] | 248 | float* x, float* y, float* radius) |
Chris Craik | e4db79d | 2015-12-22 16:32:23 -0800 | [diff] [blame] | 249 | : RecordedOp(RecordedOpId::CirclePropsOp, Rect(), localMatrix, localClip, paint) |
Chris Craik | 268a9c0 | 2015-12-09 18:05:12 -0800 | [diff] [blame] | 250 | , x(x) |
| 251 | , y(y) |
| 252 | , radius(radius) {} |
| 253 | const float* x; |
| 254 | const float* y; |
| 255 | const float* radius; |
| 256 | }; |
| 257 | |
Chris Craik | a204848 | 2016-03-25 14:17:49 -0700 | [diff] [blame] | 258 | struct ColorOp : RecordedOp { |
| 259 | // Note: unbounded op that will fillclip, so no bounds/matrix needed |
Mike Reed | 260ab72 | 2016-10-07 15:59:20 -0400 | [diff] [blame] | 260 | ColorOp(const ClipBase* localClip, int color, SkBlendMode mode) |
Chris Craik | a204848 | 2016-03-25 14:17:49 -0700 | [diff] [blame] | 261 | : RecordedOp(RecordedOpId::ColorOp, Rect(), Matrix4::identity(), localClip, nullptr) |
| 262 | , color(color) |
| 263 | , mode(mode) {} |
| 264 | const int color; |
Mike Reed | 260ab72 | 2016-10-07 15:59:20 -0400 | [diff] [blame] | 265 | const SkBlendMode mode; |
Chris Craik | a204848 | 2016-03-25 14:17:49 -0700 | [diff] [blame] | 266 | }; |
| 267 | |
Chris Craik | e29ce6f | 2015-12-10 16:25:13 -0800 | [diff] [blame] | 268 | struct FunctorOp : RecordedOp { |
Chris Craik | 4c3980b | 2016-03-15 14:20:18 -0700 | [diff] [blame] | 269 | // Note: undefined record-time bounds, since this op fills the clip |
| 270 | // TODO: explicitly define bounds |
| 271 | FunctorOp(const Matrix4& localMatrix, const ClipBase* localClip, Functor* functor) |
| 272 | : RecordedOp(RecordedOpId::FunctorOp, Rect(), localMatrix, localClip, nullptr) |
Chris Craik | e29ce6f | 2015-12-10 16:25:13 -0800 | [diff] [blame] | 273 | , functor(functor) {} |
| 274 | Functor* functor; |
| 275 | }; |
| 276 | |
Chris Craik | a171727 | 2015-11-19 13:02:43 -0800 | [diff] [blame] | 277 | struct LinesOp : RecordedOp { |
| 278 | LinesOp(BASE_PARAMS, const float* points, const int floatCount) |
| 279 | : SUPER(LinesOp) |
| 280 | , points(points) |
| 281 | , floatCount(floatCount) {} |
| 282 | const float* points; |
| 283 | const int floatCount; |
| 284 | }; |
| 285 | |
Chris Craik | 386aa03 | 2015-12-07 17:08:25 -0800 | [diff] [blame] | 286 | struct OvalOp : RecordedOp { |
| 287 | OvalOp(BASE_PARAMS) |
| 288 | : SUPER(OvalOp) {} |
| 289 | }; |
| 290 | |
Chris Craik | f09ff5a | 2015-12-08 17:21:58 -0800 | [diff] [blame] | 291 | struct PatchOp : RecordedOp { |
sergeyv | ec4a4b1 | 2016-10-20 18:39:04 -0700 | [diff] [blame] | 292 | PatchOp(BASE_PARAMS, Bitmap* bitmap, const Res_png_9patch* patch) |
Chris Craik | f09ff5a | 2015-12-08 17:21:58 -0800 | [diff] [blame] | 293 | : SUPER(PatchOp) |
| 294 | , bitmap(bitmap) |
| 295 | , patch(patch) {} |
sergeyv | ec4a4b1 | 2016-10-20 18:39:04 -0700 | [diff] [blame] | 296 | Bitmap* bitmap; |
Chris Craik | f09ff5a | 2015-12-08 17:21:58 -0800 | [diff] [blame] | 297 | const Res_png_9patch* patch; |
| 298 | }; |
| 299 | |
Chris Craik | 386aa03 | 2015-12-07 17:08:25 -0800 | [diff] [blame] | 300 | struct PathOp : RecordedOp { |
| 301 | PathOp(BASE_PARAMS, const SkPath* path) |
| 302 | : SUPER(PathOp) |
| 303 | , path(path) {} |
| 304 | const SkPath* path; |
| 305 | }; |
| 306 | |
| 307 | struct PointsOp : RecordedOp { |
| 308 | PointsOp(BASE_PARAMS, const float* points, const int floatCount) |
| 309 | : SUPER(PointsOp) |
| 310 | , points(points) |
| 311 | , floatCount(floatCount) {} |
| 312 | const float* points; |
| 313 | const int floatCount; |
| 314 | }; |
| 315 | |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 316 | struct RectOp : RecordedOp { |
| 317 | RectOp(BASE_PARAMS) |
| 318 | : SUPER(RectOp) {} |
| 319 | }; |
| 320 | |
Chris Craik | 386aa03 | 2015-12-07 17:08:25 -0800 | [diff] [blame] | 321 | struct RoundRectOp : RecordedOp { |
| 322 | RoundRectOp(BASE_PARAMS, float rx, float ry) |
| 323 | : SUPER(RoundRectOp) |
| 324 | , rx(rx) |
| 325 | , ry(ry) {} |
| 326 | const float rx; |
| 327 | const float ry; |
| 328 | }; |
| 329 | |
Chris Craik | 268a9c0 | 2015-12-09 18:05:12 -0800 | [diff] [blame] | 330 | struct RoundRectPropsOp : RecordedOp { |
Chris Craik | e4db79d | 2015-12-22 16:32:23 -0800 | [diff] [blame] | 331 | RoundRectPropsOp(const Matrix4& localMatrix, const ClipBase* localClip, const SkPaint* paint, |
Chris Craik | 268a9c0 | 2015-12-09 18:05:12 -0800 | [diff] [blame] | 332 | float* left, float* top, float* right, float* bottom, float *rx, float *ry) |
Chris Craik | e4db79d | 2015-12-22 16:32:23 -0800 | [diff] [blame] | 333 | : RecordedOp(RecordedOpId::RoundRectPropsOp, Rect(), localMatrix, localClip, paint) |
Chris Craik | 268a9c0 | 2015-12-09 18:05:12 -0800 | [diff] [blame] | 334 | , left(left) |
| 335 | , top(top) |
| 336 | , right(right) |
| 337 | , bottom(bottom) |
| 338 | , rx(rx) |
| 339 | , ry(ry) {} |
| 340 | const float* left; |
| 341 | const float* top; |
| 342 | const float* right; |
| 343 | const float* bottom; |
| 344 | const float* rx; |
| 345 | const float* ry; |
| 346 | }; |
| 347 | |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 348 | struct VectorDrawableOp : RecordedOp { |
| 349 | VectorDrawableOp(VectorDrawable::Tree* tree, BASE_PARAMS_PAINTLESS) |
| 350 | : SUPER_PAINTLESS(VectorDrawableOp) |
| 351 | , vectorDrawable(tree) {} |
| 352 | VectorDrawable::Tree* vectorDrawable; |
| 353 | }; |
| 354 | |
Chris Craik | d3daa31 | 2015-11-06 10:59:56 -0800 | [diff] [blame] | 355 | /** |
| 356 | * Real-time, dynamic-lit shadow. |
| 357 | * |
| 358 | * Uses invalid/empty bounds and matrix since ShadowOp bounds aren't known at defer time, |
| 359 | * and are resolved dynamically, and transform isn't needed. |
| 360 | * |
Chris Craik | 98787e6 | 2015-11-13 10:55:30 -0800 | [diff] [blame] | 361 | * State construction handles these properties specially, ignoring matrix/bounds. |
Chris Craik | d3daa31 | 2015-11-06 10:59:56 -0800 | [diff] [blame] | 362 | */ |
| 363 | struct ShadowOp : RecordedOp { |
Chris Craik | 6e068c01 | 2016-01-15 16:15:30 -0800 | [diff] [blame] | 364 | ShadowOp(sp<TessellationCache::ShadowTask>& shadowTask, float casterAlpha) |
Chris Craik | e4db79d | 2015-12-22 16:32:23 -0800 | [diff] [blame] | 365 | : RecordedOp(RecordedOpId::ShadowOp, Rect(), Matrix4::identity(), nullptr, nullptr) |
Chris Craik | 6e068c01 | 2016-01-15 16:15:30 -0800 | [diff] [blame] | 366 | , shadowTask(shadowTask) |
| 367 | , casterAlpha(casterAlpha) { |
Chris Craik | d3daa31 | 2015-11-06 10:59:56 -0800 | [diff] [blame] | 368 | }; |
Chris Craik | 6e068c01 | 2016-01-15 16:15:30 -0800 | [diff] [blame] | 369 | sp<TessellationCache::ShadowTask> shadowTask; |
Chris Craik | d3daa31 | 2015-11-06 10:59:56 -0800 | [diff] [blame] | 370 | const float casterAlpha; |
Chris Craik | d3daa31 | 2015-11-06 10:59:56 -0800 | [diff] [blame] | 371 | }; |
| 372 | |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 373 | struct SimpleRectsOp : RecordedOp { // Filled, no AA (TODO: better name?) |
| 374 | SimpleRectsOp(BASE_PARAMS, Vertex* vertices, size_t vertexCount) |
| 375 | : SUPER(SimpleRectsOp) |
| 376 | , vertices(vertices) |
| 377 | , vertexCount(vertexCount) {} |
| 378 | Vertex* vertices; |
| 379 | const size_t vertexCount; |
| 380 | }; |
| 381 | |
Chris Craik | a171727 | 2015-11-19 13:02:43 -0800 | [diff] [blame] | 382 | struct TextOp : RecordedOp { |
| 383 | TextOp(BASE_PARAMS, const glyph_t* glyphs, const float* positions, int glyphCount, |
| 384 | float x, float y) |
| 385 | : SUPER(TextOp) |
| 386 | , glyphs(glyphs) |
| 387 | , positions(positions) |
| 388 | , glyphCount(glyphCount) |
| 389 | , x(x) |
| 390 | , y(y) {} |
| 391 | const glyph_t* glyphs; |
| 392 | const float* positions; |
| 393 | const int glyphCount; |
| 394 | const float x; |
| 395 | const float y; |
| 396 | }; |
| 397 | |
Chris Craik | d7448e6 | 2015-12-15 10:34:36 -0800 | [diff] [blame] | 398 | struct TextOnPathOp : RecordedOp { |
Chris Craik | 4c3980b | 2016-03-15 14:20:18 -0700 | [diff] [blame] | 399 | // TODO: explicitly define bounds |
| 400 | TextOnPathOp(const Matrix4& localMatrix, const ClipBase* localClip, const SkPaint* paint, |
| 401 | const glyph_t* glyphs, int glyphCount, const SkPath* path, float hOffset, float vOffset) |
| 402 | : RecordedOp(RecordedOpId::TextOnPathOp, Rect(), localMatrix, localClip, paint) |
Chris Craik | d7448e6 | 2015-12-15 10:34:36 -0800 | [diff] [blame] | 403 | , glyphs(glyphs) |
| 404 | , glyphCount(glyphCount) |
| 405 | , path(path) |
| 406 | , hOffset(hOffset) |
| 407 | , vOffset(vOffset) {} |
| 408 | const glyph_t* glyphs; |
| 409 | const int glyphCount; |
| 410 | |
| 411 | const SkPath* path; |
| 412 | const float hOffset; |
| 413 | const float vOffset; |
| 414 | }; |
| 415 | |
Chris Craik | d2dfd8f | 2015-12-16 14:27:20 -0800 | [diff] [blame] | 416 | struct TextureLayerOp : RecordedOp { |
Greg Daniel | 8cd3edf | 2017-01-09 14:15:41 -0500 | [diff] [blame] | 417 | TextureLayerOp(BASE_PARAMS_PAINTLESS, GlLayer* layer) |
Chris Craik | d2dfd8f | 2015-12-16 14:27:20 -0800 | [diff] [blame] | 418 | : SUPER_PAINTLESS(TextureLayerOp) |
| 419 | , layer(layer) {} |
Chris Craik | aafb01d | 2016-03-25 18:34:11 -0700 | [diff] [blame] | 420 | |
| 421 | // Copy an existing TextureLayerOp, replacing the underlying matrix |
| 422 | TextureLayerOp(const TextureLayerOp& op, const Matrix4& replacementMatrix) |
| 423 | : RecordedOp(RecordedOpId::TextureLayerOp, op.unmappedBounds, replacementMatrix, |
| 424 | op.localClip, op.paint) |
| 425 | , layer(op.layer) { |
| 426 | |
| 427 | } |
Greg Daniel | 8cd3edf | 2017-01-09 14:15:41 -0500 | [diff] [blame] | 428 | GlLayer* layer; |
Chris Craik | d2dfd8f | 2015-12-16 14:27:20 -0800 | [diff] [blame] | 429 | }; |
| 430 | |
Chris Craik | a171727 | 2015-11-19 13:02:43 -0800 | [diff] [blame] | 431 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 432 | // Layers |
| 433 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 434 | |
Chris Craik | 6fe991e5 | 2015-10-20 09:39:42 -0700 | [diff] [blame] | 435 | /** |
| 436 | * Stateful operation! denotes the creation of an off-screen layer, |
| 437 | * and that commands following will render into it. |
| 438 | */ |
| 439 | struct BeginLayerOp : RecordedOp { |
| 440 | BeginLayerOp(BASE_PARAMS) |
| 441 | : SUPER(BeginLayerOp) {} |
| 442 | }; |
| 443 | |
| 444 | /** |
| 445 | * Stateful operation! Denotes end of off-screen layer, and that |
| 446 | * commands since last BeginLayerOp should be drawn into parent FBO. |
| 447 | * |
| 448 | * State in this op is empty, it just serves to signal that a layer has been finished. |
| 449 | */ |
| 450 | struct EndLayerOp : RecordedOp { |
| 451 | EndLayerOp() |
Chris Craik | e4db79d | 2015-12-22 16:32:23 -0800 | [diff] [blame] | 452 | : RecordedOp(RecordedOpId::EndLayerOp, Rect(), Matrix4::identity(), nullptr, nullptr) {} |
Chris Craik | 6fe991e5 | 2015-10-20 09:39:42 -0700 | [diff] [blame] | 453 | }; |
| 454 | |
Chris Craik | b87eadd | 2016-01-06 09:16:05 -0800 | [diff] [blame] | 455 | struct BeginUnclippedLayerOp : RecordedOp { |
| 456 | BeginUnclippedLayerOp(BASE_PARAMS) |
| 457 | : SUPER(BeginUnclippedLayerOp) {} |
| 458 | }; |
| 459 | |
| 460 | struct EndUnclippedLayerOp : RecordedOp { |
| 461 | EndUnclippedLayerOp() |
| 462 | : RecordedOp(RecordedOpId::EndUnclippedLayerOp, Rect(), Matrix4::identity(), nullptr, nullptr) {} |
| 463 | }; |
| 464 | |
| 465 | struct CopyToLayerOp : RecordedOp { |
| 466 | CopyToLayerOp(const RecordedOp& op, OffscreenBuffer** layerHandle) |
| 467 | : RecordedOp(RecordedOpId::CopyToLayerOp, |
| 468 | op.unmappedBounds, |
| 469 | op.localMatrix, |
| 470 | nullptr, // clip intentionally ignored |
| 471 | op.paint) |
| 472 | , layerHandle(layerHandle) {} |
| 473 | |
| 474 | // Records a handle to the Layer object, since the Layer itself won't be |
| 475 | // constructed until after this operation is constructed. |
| 476 | OffscreenBuffer** layerHandle; |
| 477 | }; |
| 478 | |
| 479 | |
| 480 | // draw the parameter layer underneath |
| 481 | struct CopyFromLayerOp : RecordedOp { |
| 482 | CopyFromLayerOp(const RecordedOp& op, OffscreenBuffer** layerHandle) |
| 483 | : RecordedOp(RecordedOpId::CopyFromLayerOp, |
| 484 | op.unmappedBounds, |
| 485 | op.localMatrix, |
| 486 | nullptr, // clip intentionally ignored |
| 487 | op.paint) |
| 488 | , layerHandle(layerHandle) {} |
| 489 | |
| 490 | // Records a handle to the Layer object, since the Layer itself won't be |
| 491 | // constructed until after this operation is constructed. |
| 492 | OffscreenBuffer** layerHandle; |
| 493 | }; |
| 494 | |
Chris Craik | 0b7e824 | 2015-10-28 16:50:44 -0700 | [diff] [blame] | 495 | /** |
| 496 | * Draws an OffscreenBuffer. |
| 497 | * |
| 498 | * Alpha, mode, and colorfilter are embedded, since LayerOps are always dynamically generated, |
| 499 | * when creating/tracking a SkPaint* during defer isn't worth the bother. |
| 500 | */ |
Chris Craik | 6fe991e5 | 2015-10-20 09:39:42 -0700 | [diff] [blame] | 501 | struct LayerOp : RecordedOp { |
Chris Craik | 74af6e2 | 2016-04-05 13:18:56 -0700 | [diff] [blame] | 502 | // Records a one-use (saveLayer) layer for drawing. |
Chris Craik | 5854b34 | 2015-10-26 15:49:56 -0700 | [diff] [blame] | 503 | LayerOp(BASE_PARAMS, OffscreenBuffer** layerHandle) |
Chris Craik | 0b7e824 | 2015-10-28 16:50:44 -0700 | [diff] [blame] | 504 | : SUPER_PAINTLESS(LayerOp) |
| 505 | , layerHandle(layerHandle) |
Chris Craik | e5b5019 | 2016-01-04 15:09:19 -0800 | [diff] [blame] | 506 | , alpha(paint ? paint->getAlpha() / 255.0f : 1.0f) |
Mike Reed | 260ab72 | 2016-10-07 15:59:20 -0400 | [diff] [blame] | 507 | , mode(PaintUtils::getBlendModeDirect(paint)) |
Chris Craik | 74af6e2 | 2016-04-05 13:18:56 -0700 | [diff] [blame] | 508 | , colorFilter(paint ? paint->getColorFilter() : nullptr) {} |
Chris Craik | 0b7e824 | 2015-10-28 16:50:44 -0700 | [diff] [blame] | 509 | |
Chih-Hung Hsieh | a619ec7 | 2016-08-29 14:52:43 -0700 | [diff] [blame] | 510 | explicit LayerOp(RenderNode& node) |
Chris Craik | b87eadd | 2016-01-06 09:16:05 -0800 | [diff] [blame] | 511 | : RecordedOp(RecordedOpId::LayerOp, Rect(node.getWidth(), node.getHeight()), Matrix4::identity(), nullptr, nullptr) |
| 512 | , layerHandle(node.getLayerHandle()) |
| 513 | , alpha(node.properties().layerProperties().alpha() / 255.0f) |
| 514 | , mode(node.properties().layerProperties().xferMode()) |
Chris Craik | 74af6e2 | 2016-04-05 13:18:56 -0700 | [diff] [blame] | 515 | , colorFilter(node.properties().layerProperties().colorFilter()) {} |
Chris Craik | 0b7e824 | 2015-10-28 16:50:44 -0700 | [diff] [blame] | 516 | |
Chris Craik | 818c9fb | 2015-10-23 14:33:42 -0700 | [diff] [blame] | 517 | // Records a handle to the Layer object, since the Layer itself won't be |
| 518 | // constructed until after this operation is constructed. |
Chris Craik | 5854b34 | 2015-10-26 15:49:56 -0700 | [diff] [blame] | 519 | OffscreenBuffer** layerHandle; |
Chris Craik | 0b7e824 | 2015-10-28 16:50:44 -0700 | [diff] [blame] | 520 | const float alpha; |
Mike Reed | 260ab72 | 2016-10-07 15:59:20 -0400 | [diff] [blame] | 521 | const SkBlendMode mode; |
Chris Craik | 0b7e824 | 2015-10-28 16:50:44 -0700 | [diff] [blame] | 522 | |
| 523 | // pointer to object owned by either LayerProperties, or a recorded Paint object in a |
| 524 | // BeginLayerOp. Lives longer than LayerOp in either case, so no skia ref counting is used. |
| 525 | SkColorFilter* colorFilter; |
Chris Craik | 6fe991e5 | 2015-10-20 09:39:42 -0700 | [diff] [blame] | 526 | }; |
| 527 | |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 528 | }; // namespace uirenderer |
| 529 | }; // namespace android |