Home | History | Annotate | Download | only in hwui
      1 /*
      2  * Copyright (C) 2018 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 #pragma once
     18 
     19 #include "CanvasTransform.h"
     20 #include "hwui/Bitmap.h"
     21 #include "hwui/Canvas.h"
     22 #include "utils/Macros.h"
     23 #include "utils/TypeLogic.h"
     24 
     25 #include "SkCanvas.h"
     26 #include "SkCanvasVirtualEnforcer.h"
     27 #include "SkDrawable.h"
     28 #include "SkNoDrawCanvas.h"
     29 #include "SkPaint.h"
     30 #include "SkPath.h"
     31 #include "SkRect.h"
     32 #include "SkTDArray.h"
     33 #include "SkTemplates.h"
     34 
     35 #include <vector>
     36 
     37 namespace android {
     38 namespace uirenderer {
     39 
     40 enum class DisplayListOpType : uint8_t {
     41 #define X(T) T,
     42 #include "DisplayListOps.in"
     43 #undef X
     44 };
     45 
     46 struct DisplayListOp {
     47     const uint8_t type : 8;
     48     const uint32_t skip : 24;
     49 };
     50 
     51 static_assert(sizeof(DisplayListOp) == 4);
     52 
     53 class RecordingCanvas;
     54 
     55 class DisplayListData final {
     56 public:
     57     DisplayListData() : mHasText(false) {}
     58     ~DisplayListData();
     59 
     60     void draw(SkCanvas* canvas) const;
     61 
     62     void reset();
     63     bool empty() const { return fUsed == 0; }
     64 
     65     void applyColorTransform(ColorTransform transform);
     66 
     67     bool hasText() const { return mHasText; }
     68     size_t usedSize() const { return fUsed; }
     69 
     70 private:
     71     friend class RecordingCanvas;
     72 
     73     void flush();
     74 
     75     void save();
     76     void saveLayer(const SkRect*, const SkPaint*, const SkImageFilter*, const SkImage*,
     77                    const SkMatrix*, SkCanvas::SaveLayerFlags);
     78     void saveBehind(const SkRect*);
     79     void restore();
     80 
     81     void concat(const SkMatrix&);
     82     void setMatrix(const SkMatrix&);
     83     void translate(SkScalar, SkScalar);
     84     void translateZ(SkScalar);
     85 
     86     void clipPath(const SkPath&, SkClipOp, bool aa);
     87     void clipRect(const SkRect&, SkClipOp, bool aa);
     88     void clipRRect(const SkRRect&, SkClipOp, bool aa);
     89     void clipRegion(const SkRegion&, SkClipOp);
     90 
     91     void drawPaint(const SkPaint&);
     92     void drawBehind(const SkPaint&);
     93     void drawPath(const SkPath&, const SkPaint&);
     94     void drawRect(const SkRect&, const SkPaint&);
     95     void drawRegion(const SkRegion&, const SkPaint&);
     96     void drawOval(const SkRect&, const SkPaint&);
     97     void drawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&);
     98     void drawRRect(const SkRRect&, const SkPaint&);
     99     void drawDRRect(const SkRRect&, const SkRRect&, const SkPaint&);
    100 
    101     void drawAnnotation(const SkRect&, const char*, SkData*);
    102     void drawDrawable(SkDrawable*, const SkMatrix*);
    103     void drawPicture(const SkPicture*, const SkMatrix*, const SkPaint*);
    104 
    105     void drawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&);
    106 
    107     void drawImage(sk_sp<const SkImage>, SkScalar, SkScalar, const SkPaint*, BitmapPalette palette);
    108     void drawImageNine(sk_sp<const SkImage>, const SkIRect&, const SkRect&, const SkPaint*);
    109     void drawImageRect(sk_sp<const SkImage>, const SkRect*, const SkRect&, const SkPaint*,
    110                        SkCanvas::SrcRectConstraint, BitmapPalette palette);
    111     void drawImageLattice(sk_sp<const SkImage>, const SkCanvas::Lattice&, const SkRect&,
    112                           const SkPaint*, BitmapPalette);
    113 
    114     void drawPatch(const SkPoint[12], const SkColor[4], const SkPoint[4], SkBlendMode,
    115                    const SkPaint&);
    116     void drawPoints(SkCanvas::PointMode, size_t, const SkPoint[], const SkPaint&);
    117     void drawVertices(const SkVertices*, const SkVertices::Bone bones[], int boneCount, SkBlendMode,
    118                       const SkPaint&);
    119     void drawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int,
    120                    SkBlendMode, const SkRect*, const SkPaint*);
    121     void drawShadowRec(const SkPath&, const SkDrawShadowRec&);
    122     void drawVectorDrawable(VectorDrawableRoot* tree);
    123 
    124     template <typename T, typename... Args>
    125     void* push(size_t, Args&&...);
    126 
    127     template <typename Fn, typename... Args>
    128     void map(const Fn[], Args...) const;
    129 
    130     SkAutoTMalloc<uint8_t> fBytes;
    131     size_t fUsed = 0;
    132     size_t fReserved = 0;
    133 
    134     bool mHasText : 1;
    135 };
    136 
    137 class RecordingCanvas final : public SkCanvasVirtualEnforcer<SkNoDrawCanvas> {
    138 public:
    139     RecordingCanvas();
    140     void reset(DisplayListData*, const SkIRect& bounds);
    141 
    142     sk_sp<SkSurface> onNewSurface(const SkImageInfo&, const SkSurfaceProps&) override;
    143 
    144     void willSave() override;
    145     SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
    146     void willRestore() override;
    147     bool onDoSaveBehind(const SkRect*) override;
    148 
    149     void onFlush() override;
    150 
    151     void didConcat(const SkMatrix&) override;
    152     void didSetMatrix(const SkMatrix&) override;
    153     void didTranslate(SkScalar, SkScalar) override;
    154 
    155     void onClipRect(const SkRect&, SkClipOp, ClipEdgeStyle) override;
    156     void onClipRRect(const SkRRect&, SkClipOp, ClipEdgeStyle) override;
    157     void onClipPath(const SkPath&, SkClipOp, ClipEdgeStyle) override;
    158     void onClipRegion(const SkRegion&, SkClipOp) override;
    159 
    160     void onDrawPaint(const SkPaint&) override;
    161     void onDrawBehind(const SkPaint&) override;
    162     void onDrawPath(const SkPath&, const SkPaint&) override;
    163     void onDrawRect(const SkRect&, const SkPaint&) override;
    164     void onDrawRegion(const SkRegion&, const SkPaint&) override;
    165     void onDrawOval(const SkRect&, const SkPaint&) override;
    166     void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override;
    167     void onDrawRRect(const SkRRect&, const SkPaint&) override;
    168     void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;
    169 
    170     void onDrawDrawable(SkDrawable*, const SkMatrix*) override;
    171     void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override;
    172     void onDrawAnnotation(const SkRect&, const char[], SkData*) override;
    173 
    174     void onDrawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&) override;
    175 
    176     void onDrawBitmap(const SkBitmap&, SkScalar, SkScalar, const SkPaint*) override;
    177     void onDrawBitmapLattice(const SkBitmap&, const Lattice&, const SkRect&,
    178                              const SkPaint*) override;
    179     void onDrawBitmapNine(const SkBitmap&, const SkIRect&, const SkRect&, const SkPaint*) override;
    180     void onDrawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint*,
    181                           SrcRectConstraint) override;
    182 
    183     void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top, const SkPaint* paint,
    184                    BitmapPalette pallete);
    185 
    186     void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
    187                        const SkPaint* paint, SrcRectConstraint constraint, BitmapPalette palette);
    188     void drawImageLattice(const sk_sp<SkImage>& image, const Lattice& lattice, const SkRect& dst,
    189                           const SkPaint* paint, BitmapPalette palette);
    190 
    191     void onDrawImage(const SkImage*, SkScalar, SkScalar, const SkPaint*) override;
    192     void onDrawImageLattice(const SkImage*, const Lattice&, const SkRect&, const SkPaint*) override;
    193     void onDrawImageNine(const SkImage*, const SkIRect&, const SkRect&, const SkPaint*) override;
    194     void onDrawImageRect(const SkImage*, const SkRect*, const SkRect&, const SkPaint*,
    195                          SrcRectConstraint) override;
    196 
    197     void onDrawPatch(const SkPoint[12], const SkColor[4], const SkPoint[4], SkBlendMode,
    198                      const SkPaint&) override;
    199     void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override;
    200     void onDrawVerticesObject(const SkVertices*, const SkVertices::Bone bones[], int boneCount,
    201                               SkBlendMode, const SkPaint&) override;
    202     void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int,
    203                      SkBlendMode, const SkRect*, const SkPaint*) override;
    204     void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override;
    205 
    206     void drawVectorDrawable(VectorDrawableRoot* tree);
    207 
    208     /**
    209      * If "isClipMayBeComplex" returns false, it is guaranteed the current clip is a rectangle.
    210      * If the return value is true, then clip may or may not be complex (there is no guarantee).
    211      */
    212     inline bool isClipMayBeComplex() { return mClipMayBeComplex; }
    213 
    214 private:
    215     typedef SkCanvasVirtualEnforcer<SkNoDrawCanvas> INHERITED;
    216 
    217     inline void setClipMayBeComplex() {
    218         if (!mClipMayBeComplex) {
    219             mComplexSaveCount = mSaveCount;
    220             mClipMayBeComplex = true;
    221         }
    222     }
    223 
    224     DisplayListData* fDL;
    225 
    226     /**
    227      * mClipMayBeComplex tracks if the current clip is a rectangle. This flag is used to promote
    228      * FunctorDrawable to a layer, if it is clipped by a non-rect.
    229      */
    230     bool mClipMayBeComplex = false;
    231 
    232     /**
    233      * mSaveCount is the current level of our save tree.
    234      */
    235     int mSaveCount = 0;
    236 
    237     /**
    238      * mComplexSaveCount is the first save level, which has a complex clip. Every level below
    239      * mComplexSaveCount is assumed to have a complex clip and every level above mComplexSaveCount
    240      * is guaranteed to not be complex.
    241      */
    242     int mComplexSaveCount = 0;
    243 };
    244 
    245 }  // namespace uirenderer
    246 }  // namespace android
    247