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, bool expandForPathTexture);
     57 
     58     // Constructor for unbounded ops *with* transform/clip
     59     ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot,
     60             const Matrix4& localTransform, const ClipBase* localClip);
     61 
     62     // Constructor for unbounded ops without transform/clip (namely shadows)
     63     ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot);
     64 
     65     // Constructor for primitive ops provided clip, and no transform
     66     ResolvedRenderState(const ClipRect* viewportRect, const Rect& dstRect);
     67 
     68     Rect computeLocalSpaceClip() const {
     69         Matrix4 inverse;
     70         inverse.loadInverse(transform);
     71 
     72         Rect outClip(clipRect());
     73         inverse.mapRect(outClip);
     74         return outClip;
     75     }
     76 
     77     const Rect& clipRect() const {
     78         return clipState->rect;
     79     }
     80 
     81     bool requiresClip() const {
     82         return clipSideFlags != OpClipSideFlags::None
     83                || CC_UNLIKELY(clipState->mode != ClipMode::Rectangle);
     84     }
     85 
     86     // returns the clip if it's needed to draw the operation, otherwise nullptr
     87     const ClipBase* getClipIfNeeded() const {
     88         return requiresClip() ? clipState : nullptr;
     89     }
     90 
     91     Matrix4 transform;
     92     const ClipBase* clipState = nullptr;
     93     Rect clippedBounds;
     94     int clipSideFlags = 0;
     95     const SkPath* localProjectionPathMask = nullptr;
     96     bool opaqueOverClippedBounds = false;
     97 };
     98 
     99 /**
    100  * Self-contained op wrapper, containing all resolved state required to draw the op.
    101  *
    102  * Stashed pointers within all point to longer lived objects, with no ownership implied.
    103  */
    104 class BakedOpState {
    105 public:
    106     static BakedOpState* tryConstruct(LinearAllocator& allocator,
    107             Snapshot& snapshot, const RecordedOp& recordedOp);
    108 
    109     static BakedOpState* tryConstructUnbounded(LinearAllocator& allocator,
    110             Snapshot& snapshot, const RecordedOp& recordedOp);
    111 
    112     enum class StrokeBehavior {
    113         // stroking is forced, regardless of style on paint (such as for lines)
    114         Forced,
    115         // stroking is defined by style on paint
    116         StyleDefined,
    117     };
    118 
    119     static BakedOpState* tryStrokeableOpConstruct(LinearAllocator& allocator,
    120             Snapshot& snapshot, const RecordedOp& recordedOp, StrokeBehavior strokeBehavior,
    121             bool expandForPathTexture);
    122 
    123     static BakedOpState* tryShadowOpConstruct(LinearAllocator& allocator,
    124             Snapshot& snapshot, const ShadowOp* shadowOpPtr);
    125 
    126     static BakedOpState* directConstruct(LinearAllocator& allocator,
    127             const ClipRect* clip, const Rect& dstRect, const RecordedOp& recordedOp);
    128 
    129     // Set opaqueOverClippedBounds. If this method isn't called, the op is assumed translucent.
    130     void setupOpacity(const SkPaint* paint);
    131 
    132     // computed state:
    133     ResolvedRenderState computedState;
    134 
    135     // simple state (straight pointer/value storage):
    136     const float alpha;
    137     const RoundRectClipState* roundRectClipState;
    138     const RecordedOp* op;
    139 
    140 private:
    141     friend class LinearAllocator;
    142 
    143     BakedOpState(LinearAllocator& allocator, Snapshot& snapshot,
    144             const RecordedOp& recordedOp, bool expandForStroke, bool expandForPathTexture)
    145             : computedState(allocator, snapshot, recordedOp, expandForStroke, expandForPathTexture)
    146             , alpha(snapshot.alpha)
    147             , roundRectClipState(snapshot.roundRectClipState)
    148             , op(&recordedOp) {}
    149 
    150     // TODO: fix this brittleness
    151     BakedOpState(LinearAllocator& allocator, Snapshot& snapshot, const RecordedOp& recordedOp)
    152             : computedState(allocator, snapshot, recordedOp.localMatrix, recordedOp.localClip)
    153             , alpha(snapshot.alpha)
    154             , roundRectClipState(snapshot.roundRectClipState)
    155             , op(&recordedOp) {}
    156 
    157     BakedOpState(LinearAllocator& allocator, Snapshot& snapshot, const ShadowOp* shadowOpPtr)
    158             : computedState(allocator, snapshot)
    159             , alpha(snapshot.alpha)
    160             , roundRectClipState(snapshot.roundRectClipState)
    161             , op(shadowOpPtr) {}
    162 
    163     BakedOpState(const ClipRect* clipRect, const Rect& dstRect, const RecordedOp& recordedOp)
    164             : computedState(clipRect, dstRect)
    165             , alpha(1.0f)
    166             , roundRectClipState(nullptr)
    167             , op(&recordedOp) {}
    168 };
    169 
    170 }; // namespace uirenderer
    171 }; // namespace android
    172 
    173 #endif // ANDROID_HWUI_BAKED_OP_STATE_H
    174