1 /* 2 * Copyright 2018 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef GrFillRRectOp_DEFINED 9 #define GrFillRRectOp_DEFINED 10 11 #include "src/gpu/GrProgramInfo.h" 12 #include "src/gpu/ops/GrDrawOp.h" 13 14 class GrRecordingContext; 15 16 class GrFillRRectOp : public GrDrawOp { 17 public: 18 DEFINE_OP_CLASS_ID 19 20 static std::unique_ptr<GrFillRRectOp> Make( 21 GrRecordingContext*, GrAAType, const SkMatrix& viewMatrix, const SkRRect&, 22 const GrCaps&, GrPaint&&); 23 name()24 const char* name() const final { return "GrFillRRectOp"; } 25 fixedFunctionFlags()26 FixedFunctionFlags fixedFunctionFlags() const final { 27 return (GrAAType::kMSAA == fAAType) ? FixedFunctionFlags::kUsesHWAA 28 : FixedFunctionFlags::kNone; 29 } 30 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, 31 bool hasMixedSampledCoverage, GrClampType) final; 32 CombineResult onCombineIfPossible(GrOp*, GrRecordingContext::Arenas*, const GrCaps&) final; visitProxies(const VisitProxyFunc & fn)33 void visitProxies(const VisitProxyFunc& fn) const override { 34 if (fProgramInfo) { 35 fProgramInfo->visitProxies(fn); 36 } else { 37 fProcessors.visitProxies(fn); 38 } 39 } 40 41 void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView*, GrAppliedClip*, 42 const GrXferProcessor::DstProxyView&) final; 43 44 void onPrepare(GrOpFlushState*) final; 45 46 void onExecute(GrOpFlushState*, const SkRect& chainBounds) final; 47 48 private: 49 enum class Flags { 50 kNone = 0, 51 kUseHWDerivatives = 1 << 0, 52 kHasPerspective = 1 << 1, 53 kHasLocalCoords = 1 << 2, 54 kWideColor = 1 << 3 55 }; 56 57 GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags); 58 59 class Processor; 60 61 GrFillRRectOp(GrAAType, const SkRRect&, Flags, const SkMatrix& totalShapeMatrix, 62 GrPaint&&, const SkRect& devBounds); 63 64 // These methods are used to append data of various POD types to our internal array of instance 65 // data. The actual layout of the instance buffer can vary from Op to Op. appendInstanceData(int count)66 template <typename T> inline T* appendInstanceData(int count) { 67 static_assert(std::is_pod<T>::value, ""); 68 static_assert(4 == alignof(T), ""); 69 return reinterpret_cast<T*>(fInstanceData.push_back_n(sizeof(T) * count)); 70 } 71 72 template <typename T, typename... Args> writeInstanceData(const T & val,const Args &...remainder)73 inline void writeInstanceData(const T& val, const Args&... remainder) { 74 memcpy(this->appendInstanceData<T>(1), &val, sizeof(T)); 75 this->writeInstanceData(remainder...); 76 } 77 writeInstanceData()78 void writeInstanceData() {} // Halt condition. 79 80 // Create a GrProgramInfo object in the provided arena 81 GrProgramInfo* createProgramInfo(const GrCaps*, 82 SkArenaAlloc*, 83 const GrSurfaceProxyView* dstView, 84 GrAppliedClip&&, 85 const GrXferProcessor::DstProxyView&); 86 87 const GrAAType fAAType; 88 const SkPMColor4f fOriginalColor; 89 const SkRect fLocalRect; 90 Flags fFlags; 91 GrProcessorSet fProcessors; 92 93 SkSTArray<sizeof(float) * 16 * 4, char, /*MEM_MOVE=*/ true> fInstanceData; 94 int fInstanceCount = 1; 95 int fInstanceStride = 0; 96 97 sk_sp<const GrBuffer> fInstanceBuffer; 98 sk_sp<const GrBuffer> fVertexBuffer; 99 sk_sp<const GrBuffer> fIndexBuffer; 100 int fBaseInstance = 0; 101 int fIndexCount = 0; 102 103 // If this op is prePrepared the created programInfo will be stored here from use in 104 // onExecute. In the prePrepared case it will have been stored in the record-time arena. 105 GrProgramInfo* fProgramInfo = nullptr; 106 107 friend class GrOpMemoryPool; 108 }; 109 110 GR_MAKE_BITFIELD_CLASS_OPS(GrFillRRectOp::Flags) 111 112 #endif 113