blob: c6ad1e28485a6f0286a91bafca656ffbca365c14 [file] [log] [blame]
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrFillRRectOp_DEFINED
#define GrFillRRectOp_DEFINED
#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/ops/GrDrawOp.h"
class GrRecordingContext;
class GrFillRRectOp : public GrDrawOp {
public:
DEFINE_OP_CLASS_ID
static std::unique_ptr<GrFillRRectOp> Make(
GrRecordingContext*, GrAAType, const SkMatrix& viewMatrix, const SkRRect&,
const GrCaps&, GrPaint&&);
const char* name() const final { return "GrFillRRectOp"; }
FixedFunctionFlags fixedFunctionFlags() const final {
return (GrAAType::kMSAA == fAAType) ? FixedFunctionFlags::kUsesHWAA
: FixedFunctionFlags::kNone;
}
GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
bool hasMixedSampledCoverage, GrClampType) final;
CombineResult onCombineIfPossible(GrOp*, const GrCaps&) final;
void visitProxies(const VisitProxyFunc& fn) const override {
if (fProgramInfo) {
fProgramInfo->visitProxies(fn);
} else {
fProcessors.visitProxies(fn);
}
}
void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView*, GrAppliedClip*,
const GrXferProcessor::DstProxyView&) final;
void onPrepare(GrOpFlushState*) final;
void onExecute(GrOpFlushState*, const SkRect& chainBounds) final;
private:
enum class Flags {
kNone = 0,
kUseHWDerivatives = 1 << 0,
kHasPerspective = 1 << 1,
kHasLocalCoords = 1 << 2,
kWideColor = 1 << 3
};
GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags);
class Processor;
GrFillRRectOp(GrAAType, const SkRRect&, Flags, const SkMatrix& totalShapeMatrix,
GrPaint&&, const SkRect& devBounds);
// These methods are used to append data of various POD types to our internal array of instance
// data. The actual layout of the instance buffer can vary from Op to Op.
template <typename T> inline T* appendInstanceData(int count) {
static_assert(std::is_pod<T>::value, "");
static_assert(4 == alignof(T), "");
return reinterpret_cast<T*>(fInstanceData.push_back_n(sizeof(T) * count));
}
template <typename T, typename... Args>
inline void writeInstanceData(const T& val, const Args&... remainder) {
memcpy(this->appendInstanceData<T>(1), &val, sizeof(T));
this->writeInstanceData(remainder...);
}
void writeInstanceData() {} // Halt condition.
// Create a GrProgramInfo object in the provided arena
GrProgramInfo* createProgramInfo(const GrCaps*,
SkArenaAlloc*,
const GrSurfaceProxyView* dstView,
GrAppliedClip&&,
const GrXferProcessor::DstProxyView&);
const GrAAType fAAType;
const SkPMColor4f fOriginalColor;
const SkRect fLocalRect;
Flags fFlags;
GrProcessorSet fProcessors;
SkSTArray<sizeof(float) * 16 * 4, char, /*MEM_MOVE=*/ true> fInstanceData;
int fInstanceCount = 1;
int fInstanceStride = 0;
sk_sp<const GrBuffer> fInstanceBuffer;
sk_sp<const GrBuffer> fVertexBuffer;
sk_sp<const GrBuffer> fIndexBuffer;
int fBaseInstance = 0;
int fIndexCount = 0;
// If this op is prePrepared the created programInfo will be stored here from use in
// onExecute. In the prePrepared case it will have been stored in the record-time arena.
GrProgramInfo* fProgramInfo = nullptr;
friend class GrOpMemoryPool;
};
GR_MAKE_BITFIELD_CLASS_OPS(GrFillRRectOp::Flags)
#endif