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 | |
| 17 | #ifndef ANDROID_HWUI_RECORDING_CANVAS_H |
| 18 | #define ANDROID_HWUI_RECORDING_CANVAS_H |
| 19 | |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 20 | #include "CanvasState.h" |
| 21 | #include "DisplayList.h" |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 22 | #include "ResourceCache.h" |
| 23 | #include "SkiaCanvasProxy.h" |
| 24 | #include "Snapshot.h" |
sergeyv | ec4a4b1 | 2016-10-20 18:39:04 -0700 | [diff] [blame] | 25 | #include "hwui/Bitmap.h" |
sergeyv | dccca44 | 2016-03-21 15:38:21 -0700 | [diff] [blame] | 26 | #include "hwui/Canvas.h" |
Chris Craik | 9fded23 | 2015-11-11 16:42:34 -0800 | [diff] [blame] | 27 | #include "utils/LinearAllocator.h" |
| 28 | #include "utils/Macros.h" |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 29 | |
Chris Craik | 0b7e824 | 2015-10-28 16:50:44 -0700 | [diff] [blame] | 30 | #include <SkDrawFilter.h> |
| 31 | #include <SkPaint.h> |
| 32 | #include <SkTLazy.h> |
| 33 | |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 34 | #include <vector> |
| 35 | |
| 36 | namespace android { |
| 37 | namespace uirenderer { |
| 38 | |
Chris Craik | e4db79d | 2015-12-22 16:32:23 -0800 | [diff] [blame] | 39 | struct ClipBase; |
Chris Craik | d2dfd8f | 2015-12-16 14:27:20 -0800 | [diff] [blame] | 40 | class DeferredLayerUpdater; |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 41 | struct RecordedOp; |
| 42 | |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 43 | class ANDROID_API RecordingCanvas : public Canvas, public CanvasStateClient { |
Chris Craik | 161f54b | 2015-11-05 11:08:52 -0800 | [diff] [blame] | 44 | enum class DeferredBarrierType { |
| 45 | None, |
| 46 | InOrder, |
| 47 | OutOfOrder, |
| 48 | }; |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 49 | |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 50 | public: |
| 51 | RecordingCanvas(size_t width, size_t height); |
| 52 | virtual ~RecordingCanvas(); |
| 53 | |
Stan Iliev | c0e7a90 | 2016-10-13 17:07:09 -0400 | [diff] [blame] | 54 | virtual void resetRecording(int width, int height, RenderNode* node = nullptr) override; |
Derek Sollenberger | 6f48556 | 2015-07-30 10:00:39 -0400 | [diff] [blame] | 55 | virtual WARN_UNUSED_RESULT DisplayList* finishRecording() override; |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 56 | // ---------------------------------------------------------------------------- |
| 57 | // MISC HWUI OPERATIONS - TODO: CATEGORIZE |
| 58 | // ---------------------------------------------------------------------------- |
Chris Craik | d645640 | 2016-04-11 12:24:23 -0700 | [diff] [blame] | 59 | virtual void insertReorderBarrier(bool enableReorder) override; |
Chris Craik | d2dfd8f | 2015-12-16 14:27:20 -0800 | [diff] [blame] | 60 | |
Derek Sollenberger | 6f48556 | 2015-07-30 10:00:39 -0400 | [diff] [blame] | 61 | virtual void drawLayer(DeferredLayerUpdater* layerHandle) override; |
| 62 | virtual void drawRenderNode(RenderNode* renderNode) override; |
John Reck | cd1c3eb | 2016-04-14 10:38:54 -0700 | [diff] [blame] | 63 | virtual void callDrawGLFunction(Functor* functor, |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 64 | GlFunctorLifecycleListener* listener) override; |
Chris Craik | e29ce6f | 2015-12-10 16:25:13 -0800 | [diff] [blame] | 65 | |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 66 | // ---------------------------------------------------------------------------- |
| 67 | // CanvasStateClient interface |
| 68 | // ---------------------------------------------------------------------------- |
Chris Craik | 6fe991e5 | 2015-10-20 09:39:42 -0700 | [diff] [blame] | 69 | virtual void onViewportInitialized() override; |
| 70 | virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) override; |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 71 | virtual GLuint getTargetFbo() const override { return -1; } |
| 72 | |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 73 | // ---------------------------------------------------------------------------- |
| 74 | // HWUI Canvas draw operations |
| 75 | // ---------------------------------------------------------------------------- |
Chris Craik | 268a9c0 | 2015-12-09 18:05:12 -0800 | [diff] [blame] | 76 | |
Derek Sollenberger | 6f48556 | 2015-07-30 10:00:39 -0400 | [diff] [blame] | 77 | virtual void drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top, |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 78 | CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom, |
| 79 | CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry, |
| 80 | CanvasPropertyPaint* paint) override; |
Derek Sollenberger | 6f48556 | 2015-07-30 10:00:39 -0400 | [diff] [blame] | 81 | virtual void drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y, |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 82 | CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) override; |
Chris Craik | 268a9c0 | 2015-12-09 18:05:12 -0800 | [diff] [blame] | 83 | |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 84 | // ---------------------------------------------------------------------------- |
| 85 | // android/graphics/Canvas interface |
| 86 | // ---------------------------------------------------------------------------- |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 87 | virtual SkCanvas* asSkCanvas() override; |
| 88 | |
| 89 | virtual void setBitmap(const SkBitmap& bitmap) override { |
| 90 | LOG_ALWAYS_FATAL("RecordingCanvas is not backed by a bitmap."); |
| 91 | } |
| 92 | |
| 93 | virtual bool isOpaque() override { return false; } |
| 94 | virtual int width() override { return mState.getWidth(); } |
| 95 | virtual int height() override { return mState.getHeight(); } |
| 96 | |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 97 | // ---------------------------------------------------------------------------- |
| 98 | // android/graphics/Canvas state operations |
| 99 | // ---------------------------------------------------------------------------- |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 100 | // Save (layer) |
| 101 | virtual int getSaveCount() const override { return mState.getSaveCount(); } |
Florin Malita | eecff56 | 2015-12-21 10:43:01 -0500 | [diff] [blame] | 102 | virtual int save(SaveFlags::Flags flags) override; |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 103 | virtual void restore() override; |
| 104 | virtual void restoreToCount(int saveCount) override; |
| 105 | |
| 106 | virtual int saveLayer(float left, float top, float right, float bottom, const SkPaint* paint, |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 107 | SaveFlags::Flags flags) override; |
| 108 | virtual int saveLayerAlpha(float left, float top, float right, float bottom, int alpha, |
| 109 | SaveFlags::Flags flags) override { |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 110 | SkPaint paint; |
| 111 | paint.setAlpha(alpha); |
| 112 | return saveLayer(left, top, right, bottom, &paint, flags); |
| 113 | } |
| 114 | |
| 115 | // Matrix |
| 116 | virtual void getMatrix(SkMatrix* outMatrix) const override { mState.getMatrix(outMatrix); } |
| 117 | virtual void setMatrix(const SkMatrix& matrix) override { mState.setMatrix(matrix); } |
| 118 | |
| 119 | virtual void concat(const SkMatrix& matrix) override { mState.concatMatrix(matrix); } |
| 120 | virtual void rotate(float degrees) override; |
| 121 | virtual void scale(float sx, float sy) override; |
| 122 | virtual void skew(float sx, float sy) override; |
| 123 | virtual void translate(float dx, float dy) override; |
| 124 | |
| 125 | // Clip |
| 126 | virtual bool getClipBounds(SkRect* outRect) const override; |
| 127 | virtual bool quickRejectRect(float left, float top, float right, float bottom) const override; |
| 128 | virtual bool quickRejectPath(const SkPath& path) const override; |
| 129 | |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 130 | virtual bool clipRect(float left, float top, float right, float bottom, SkClipOp op) override; |
Mike Reed | 6e49c9f | 2016-12-02 15:36:59 -0500 | [diff] [blame] | 131 | virtual bool clipPath(const SkPath* path, SkClipOp op) override; |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 132 | |
| 133 | // Misc |
| 134 | virtual SkDrawFilter* getDrawFilter() override { return mDrawFilter.get(); } |
| 135 | virtual void setDrawFilter(SkDrawFilter* filter) override { |
| 136 | mDrawFilter.reset(SkSafeRef(filter)); |
| 137 | } |
| 138 | |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 139 | // ---------------------------------------------------------------------------- |
| 140 | // android/graphics/Canvas draw operations |
| 141 | // ---------------------------------------------------------------------------- |
Mike Reed | 260ab72 | 2016-10-07 15:59:20 -0400 | [diff] [blame] | 142 | virtual void drawColor(int color, SkBlendMode mode) override; |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 143 | virtual void drawPaint(const SkPaint& paint) override; |
| 144 | |
| 145 | // Geometry |
| 146 | virtual void drawPoint(float x, float y, const SkPaint& paint) override { |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 147 | float points[2] = {x, y}; |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 148 | drawPoints(points, 2, paint); |
| 149 | } |
Chris Craik | 386aa03 | 2015-12-07 17:08:25 -0800 | [diff] [blame] | 150 | virtual void drawPoints(const float* points, int floatCount, const SkPaint& paint) override; |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 151 | virtual void drawLine(float startX, float startY, float stopX, float stopY, |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 152 | const SkPaint& paint) override { |
| 153 | float points[4] = {startX, startY, stopX, stopY}; |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 154 | drawLines(points, 4, paint); |
| 155 | } |
Chris Craik | 386aa03 | 2015-12-07 17:08:25 -0800 | [diff] [blame] | 156 | virtual void drawLines(const float* points, int floatCount, const SkPaint& paint) override; |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 157 | virtual void drawRect(float left, float top, float right, float bottom, |
| 158 | const SkPaint& paint) override; |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 159 | virtual void drawRegion(const SkRegion& region, const SkPaint& paint) override; |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 160 | virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, |
| 161 | const SkPaint& paint) override; |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 162 | virtual void drawCircle(float x, float y, float radius, const SkPaint& paint) override; |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 163 | virtual void drawOval(float left, float top, float right, float bottom, |
| 164 | const SkPaint& paint) override; |
| 165 | virtual void drawArc(float left, float top, float right, float bottom, float startAngle, |
| 166 | float sweepAngle, bool useCenter, const SkPaint& paint) override; |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 167 | virtual void drawPath(const SkPath& path, const SkPaint& paint) override; |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 168 | virtual void drawVertices(const SkVertices*, SkBlendMode, const SkPaint& paint) |
| 169 | override { /* RecordingCanvas does not support drawVertices(); ignore */ |
| 170 | } |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 171 | |
Doris Liu | 766431a | 2016-02-04 22:17:11 +0000 | [diff] [blame] | 172 | virtual void drawVectorDrawable(VectorDrawableRoot* tree) override; |
| 173 | |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 174 | // Bitmap-based |
sergeyv | aed7f58 | 2016-10-14 16:30:21 -0700 | [diff] [blame] | 175 | virtual void drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) override; |
sergeyv | fc999950 | 2016-10-17 13:07:38 -0700 | [diff] [blame] | 176 | virtual void drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint) override; |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 177 | virtual void drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop, float srcRight, |
| 178 | float srcBottom, float dstLeft, float dstTop, float dstRight, |
| 179 | float dstBottom, const SkPaint* paint) override; |
sergeyv | 5fd2a1c | 2016-10-20 15:04:28 -0700 | [diff] [blame] | 180 | virtual void drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight, |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 181 | const float* vertices, const int* colors, |
| 182 | const SkPaint* paint) override; |
| 183 | virtual void drawNinePatch(Bitmap& bitmap, const android::Res_png_9patch& chunk, float dstLeft, |
| 184 | float dstTop, float dstRight, float dstBottom, |
| 185 | const SkPaint* paint) override; |
Derek Sollenberger | 2d14213 | 2018-01-22 10:25:26 -0500 | [diff] [blame] | 186 | virtual double drawAnimatedImage(AnimatedImageDrawable*) override; |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 187 | |
| 188 | // Text |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 189 | virtual bool drawTextAbsolutePos() const override { return false; } |
| 190 | |
Derek Sollenberger | 79abbf2 | 2016-03-24 11:07:19 -0400 | [diff] [blame] | 191 | protected: |
Stan Iliev | 0b58d99 | 2017-03-30 18:22:27 -0400 | [diff] [blame] | 192 | virtual void drawGlyphs(ReadGlyphFunc glyphFunc, int count, const SkPaint& paint, float x, |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 193 | float y, float boundsLeft, float boundsTop, float boundsRight, |
| 194 | float boundsBottom, float totalAdvance) override; |
Yuqian Li | afc22149 | 2016-07-18 13:07:42 -0400 | [diff] [blame] | 195 | virtual void drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset, |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 196 | const SkPaint& paint, const SkPath& path, size_t start, |
| 197 | size_t end) override; |
Derek Sollenberger | 79abbf2 | 2016-03-24 11:07:19 -0400 | [diff] [blame] | 198 | |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 199 | private: |
Chris Craik | e4db79d | 2015-12-22 16:32:23 -0800 | [diff] [blame] | 200 | const ClipBase* getRecordedClip() { |
| 201 | return mState.writableSnapshot()->mutateClipArea().serializeClip(alloc()); |
| 202 | } |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 203 | |
sergeyv | ec4a4b1 | 2016-10-20 18:39:04 -0700 | [diff] [blame] | 204 | void drawBitmap(Bitmap& bitmap, const SkPaint* paint); |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 205 | void drawSimpleRects(const float* rects, int vertexCount, const SkPaint* paint); |
| 206 | |
Chris Craik | 3c53ec5 | 2016-08-08 15:15:57 -0700 | [diff] [blame] | 207 | int addOp(RecordedOp* op); |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 208 | // ---------------------------------------------------------------------------- |
| 209 | // lazy object copy |
| 210 | // ---------------------------------------------------------------------------- |
Chris Craik | 003cc3d | 2015-10-16 10:24:55 -0700 | [diff] [blame] | 211 | LinearAllocator& alloc() { return mDisplayList->allocator; } |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 212 | |
| 213 | void refBitmapsInShader(const SkShader* shader); |
| 214 | |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 215 | template <class T> |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 216 | inline const T* refBuffer(const T* srcBuffer, int32_t count) { |
| 217 | if (!srcBuffer) return nullptr; |
| 218 | |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 219 | T* dstBuffer = (T*)mDisplayList->allocator.alloc<T>(count * sizeof(T)); |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 220 | memcpy(dstBuffer, srcBuffer, count * sizeof(T)); |
| 221 | return dstBuffer; |
| 222 | } |
| 223 | |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 224 | inline const SkPath* refPath(const SkPath* path) { |
| 225 | if (!path) return nullptr; |
| 226 | |
| 227 | // The points/verbs within the path are refcounted so this copy operation |
| 228 | // is inexpensive and maintains the generationID of the original path. |
| 229 | const SkPath* cachedPath = new SkPath(*path); |
Chris Craik | 003cc3d | 2015-10-16 10:24:55 -0700 | [diff] [blame] | 230 | mDisplayList->pathResources.push_back(cachedPath); |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 231 | return cachedPath; |
| 232 | } |
| 233 | |
Chris Craik | a171727 | 2015-11-19 13:02:43 -0800 | [diff] [blame] | 234 | /** |
Chris Craik | 42a5407 | 2015-11-24 11:41:54 -0800 | [diff] [blame] | 235 | * Returns a RenderThread-safe, const copy of the SkPaint parameter passed in |
| 236 | * (with deduping based on paint hash / equality check) |
Chris Craik | a171727 | 2015-11-19 13:02:43 -0800 | [diff] [blame] | 237 | */ |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 238 | inline const SkPaint* refPaint(const SkPaint* paint) { |
| 239 | if (!paint) return nullptr; |
| 240 | |
| 241 | // If there is a draw filter apply it here and store the modified paint |
| 242 | // so that we don't need to modify the paint every time we access it. |
| 243 | SkTLazy<SkPaint> filteredPaint; |
| 244 | if (mDrawFilter.get()) { |
| 245 | filteredPaint.set(*paint); |
| 246 | mDrawFilter->filter(filteredPaint.get(), SkDrawFilter::kPaint_Type); |
| 247 | paint = filteredPaint.get(); |
| 248 | } |
| 249 | |
| 250 | // compute the hash key for the paint and check the cache. |
| 251 | const uint32_t key = paint->getHash(); |
| 252 | const SkPaint* cachedPaint = mPaintMap.valueFor(key); |
| 253 | // In the unlikely event that 2 unique paints have the same hash we do a |
| 254 | // object equality check to ensure we don't erroneously dedup them. |
| 255 | if (cachedPaint == nullptr || *cachedPaint != *paint) { |
Chris Craik | 42a5407 | 2015-11-24 11:41:54 -0800 | [diff] [blame] | 256 | cachedPaint = new SkPaint(*paint); |
| 257 | mDisplayList->paints.emplace_back(cachedPaint); |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 258 | // replaceValueFor() performs an add if the entry doesn't exist |
| 259 | mPaintMap.replaceValueFor(key, cachedPaint); |
| 260 | refBitmapsInShader(cachedPaint->getShader()); |
| 261 | } |
| 262 | |
| 263 | return cachedPaint; |
| 264 | } |
| 265 | |
| 266 | inline const SkRegion* refRegion(const SkRegion* region) { |
| 267 | if (!region) { |
| 268 | return region; |
| 269 | } |
| 270 | |
| 271 | const SkRegion* cachedRegion = mRegionMap.valueFor(region); |
| 272 | // TODO: Add generation ID to SkRegion |
| 273 | if (cachedRegion == nullptr) { |
| 274 | std::unique_ptr<const SkRegion> copy(new SkRegion(*region)); |
| 275 | cachedRegion = copy.get(); |
Chris Craik | 003cc3d | 2015-10-16 10:24:55 -0700 | [diff] [blame] | 276 | mDisplayList->regions.push_back(std::move(copy)); |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 277 | |
| 278 | // replaceValueFor() performs an add if the entry doesn't exist |
| 279 | mRegionMap.replaceValueFor(region, cachedRegion); |
| 280 | } |
| 281 | |
| 282 | return cachedRegion; |
| 283 | } |
| 284 | |
sergeyv | ec4a4b1 | 2016-10-20 18:39:04 -0700 | [diff] [blame] | 285 | inline Bitmap* refBitmap(Bitmap& bitmap) { |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 286 | // Note that this assumes the bitmap is immutable. There are cases this won't handle |
| 287 | // correctly, such as creating the bitmap from scratch, drawing with it, changing its |
| 288 | // contents, and drawing again. The only fix would be to always copy it the first time, |
| 289 | // which doesn't seem worth the extra cycles for this unlikely case. |
sergeyv | ec4a4b1 | 2016-10-20 18:39:04 -0700 | [diff] [blame] | 290 | |
| 291 | // this is required because sk_sp's ctor adopts the pointer, |
| 292 | // but does not increment the refcount, |
| 293 | bitmap.ref(); |
| 294 | mDisplayList->bitmapResources.emplace_back(&bitmap); |
| 295 | return &bitmap; |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 296 | } |
| 297 | |
| 298 | inline const Res_png_9patch* refPatch(const Res_png_9patch* patch) { |
Chris Craik | 003cc3d | 2015-10-16 10:24:55 -0700 | [diff] [blame] | 299 | mDisplayList->patchResources.push_back(patch); |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 300 | mResourceCache.incrementRefcount(patch); |
| 301 | return patch; |
| 302 | } |
| 303 | |
| 304 | DefaultKeyedVector<uint32_t, const SkPaint*> mPaintMap; |
| 305 | DefaultKeyedVector<const SkPath*, const SkPath*> mPathMap; |
| 306 | DefaultKeyedVector<const SkRegion*, const SkRegion*> mRegionMap; |
| 307 | |
| 308 | CanvasState mState; |
| 309 | std::unique_ptr<SkiaCanvasProxy> mSkiaCanvasProxy; |
| 310 | ResourceCache& mResourceCache; |
Chris Craik | 161f54b | 2015-11-05 11:08:52 -0800 | [diff] [blame] | 311 | DeferredBarrierType mDeferredBarrierType = DeferredBarrierType::None; |
Chris Craik | d645640 | 2016-04-11 12:24:23 -0700 | [diff] [blame] | 312 | const ClipBase* mDeferredBarrierClip = nullptr; |
Chris Craik | 003cc3d | 2015-10-16 10:24:55 -0700 | [diff] [blame] | 313 | DisplayList* mDisplayList = nullptr; |
Ben Wagner | 18bd885 | 2016-10-24 14:50:10 -0400 | [diff] [blame] | 314 | sk_sp<SkDrawFilter> mDrawFilter; |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 315 | }; // class RecordingCanvas |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 316 | |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 317 | }; // namespace uirenderer |
| 318 | }; // namespace android |
Chris Craik | b565df1 | 2015-10-05 13:00:52 -0700 | [diff] [blame] | 319 | |
John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 320 | #endif // ANDROID_HWUI_RECORDING_CANVAS_H |