Home | History | Annotate | Download | only in hwui
      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_BAKED_OP_STATE_H
     18 #define ANDROID_HWUI_BAKED_OP_STATE_H
     19 
     20 #include "Matrix.h"
     21 #include "RecordedOp.h"
     22 #include "Rect.h"
     23 #include "Snapshot.h"
     24 
     25 namespace android {
     26 namespace uirenderer {
     27 
     28 namespace OpClipSideFlags {
     29 enum {
     30     None = 0x0,
     31     Left = 0x1,
     32     Top = 0x2,
     33     Right = 0x4,
     34     Bottom = 0x8,
     35     Full = 0xF,
     36     // ConservativeFull = 0x1F  needed?
     37 };
     38 }
     39 
     40 /**
     41  * Holds a list of BakedOpStates of ops that can be drawn together
     42  */
     43 struct MergedBakedOpList {
     44     const BakedOpState* const* states;
     45     size_t count;
     46     int clipSideFlags;
     47     Rect clip;
     48 };
     49 
     50 /**
     51  * Holds the resolved clip, transform, and bounds of a recordedOp, when replayed with a snapshot
     52  */
     53 class ResolvedRenderState {
     54 public:
     55     ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot,
     56                         const RecordedOp& recordedOp, bool expandForStroke,
     57                         bool expandForPathTexture);
     58 
     59     // Constructor for unbounded ops *with* transform/clip
     60     ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot,
     61                         const Matrix4& localTransform, const ClipBase* localClip);
     62 
     63     // Constructor for unbounded ops without transform/clip (namely shadows)
     64     ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot);
     65 
     66     // Constructor for primitive ops provided clip, and no transform
     67     ResolvedRenderState(const ClipRect* viewportRect, const Rect& dstRect);
     68 
     69     Rect computeLocalSpaceClip() const {
     70         Matrix4 inverse;
     71         inverse.loadInverse(transform);
     72 
     73         Rect outClip(clipRect());
     74         inverse.mapRect(outClip);
     75         return outClip;
     76     }
     77 
     78     const Rect& clipRect() const { return clipState->rect; }
     79 
     80     bool requiresClip() const {
     81         return clipSideFlags != OpClipSideFlags::None ||
     82                CC_UNLIKELY(clipState->mode != ClipMode::Rectangle);
     83     }
     84 
     85     // returns the clip if it's needed to draw the operation, otherwise nullptr
     86     const ClipBase* getClipIfNeeded() const { return requiresClip() ? clipState : nullptr; }
     87 
     88     Matrix4 transform;
     89     const ClipBase* clipState = nullptr;
     90     Rect clippedBounds;
     91     int clipSideFlags = 0;
     92     const SkPath* localProjectionPathMask = nullptr;
     93     bool opaqueOverClippedBounds = false;
     94 };
     95 
     96 /**
     97  * Self-contained op wrapper, containing all resolved state required to draw the op.
     98  *
     99  * Stashed pointers within all point to longer lived objects, with no ownership implied.
    100  */
    101 class BakedOpState {
    102 public:
    103     static BakedOpState* tryConstruct(LinearAllocator& allocator, Snapshot& snapshot,
    104                                       const RecordedOp& recordedOp);
    105 
    106     static BakedOpState* tryConstructUnbounded(LinearAllocator& allocator, Snapshot& snapshot,
    107                                                const RecordedOp& recordedOp);
    108 
    109     enum class StrokeBehavior {
    110         // stroking is forced, regardless of style on paint (such as for lines)
    111         Forced,
    112         // stroking is defined by style on paint
    113         StyleDefined,
    114     };
    115 
    116     static BakedOpState* tryStrokeableOpConstruct(LinearAllocator& allocator, Snapshot& snapshot,
    117                                                   const RecordedOp& recordedOp,
    118                                                   StrokeBehavior strokeBehavior,
    119                                                   bool expandForPathTexture);
    120 
    121     static BakedOpState* tryShadowOpConstruct(LinearAllocator& allocator, Snapshot& snapshot,
    122                                               const ShadowOp* shadowOpPtr);
    123 
    124     static BakedOpState* directConstruct(LinearAllocator& allocator, const ClipRect* clip,
    125                                          const Rect& dstRect, const RecordedOp& recordedOp);
    126 
    127     // Set opaqueOverClippedBounds. If this method isn't called, the op is assumed translucent.
    128     void setupOpacity(const SkPaint* paint);
    129 
    130     // computed state:
    131     ResolvedRenderState computedState;
    132 
    133     // simple state (straight pointer/value storage):
    134     const float alpha;
    135     const RoundRectClipState* roundRectClipState;
    136     const RecordedOp* op;
    137 
    138 private:
    139     friend class LinearAllocator;
    140 
    141     BakedOpState(LinearAllocator& allocator, Snapshot& snapshot, const RecordedOp& recordedOp,
    142                  bool expandForStroke, bool expandForPathTexture)
    143             : computedState(allocator, snapshot, recordedOp, expandForStroke, expandForPathTexture)
    144             , alpha(snapshot.alpha)
    145             , roundRectClipState(snapshot.roundRectClipState)
    146             , op(&recordedOp) {}
    147 
    148     // TODO: fix this brittleness
    149     BakedOpState(LinearAllocator& allocator, Snapshot& snapshot, const RecordedOp& recordedOp)
    150             : computedState(allocator, snapshot, recordedOp.localMatrix, recordedOp.localClip)
    151             , alpha(snapshot.alpha)
    152             , roundRectClipState(snapshot.roundRectClipState)
    153             , op(&recordedOp) {}
    154 
    155     BakedOpState(LinearAllocator& allocator, Snapshot& snapshot, const ShadowOp* shadowOpPtr)
    156             : computedState(allocator, snapshot)
    157             , alpha(snapshot.alpha)
    158             , roundRectClipState(snapshot.roundRectClipState)
    159             , op(shadowOpPtr) {}
    160 
    161     BakedOpState(const ClipRect* clipRect, const Rect& dstRect, const RecordedOp& recordedOp)
    162             : computedState(clipRect, dstRect)
    163             , alpha(1.0f)
    164             , roundRectClipState(nullptr)
    165             , op(&recordedOp) {}
    166 };
    167 
    168 };  // namespace uirenderer
    169 };  // namespace android
    170 
    171 #endif  // ANDROID_HWUI_BAKED_OP_STATE_H
    172