#include "src/gpu/ganesh/ops/StrokeRectOp.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkString.h"
#include "include/core/SkStrokeRec.h"
#include "include/gpu/ganesh/GrRecordingContext.h"
#include "include/private/SkColorData.h"
#include "include/private/base/SkAlignedStorage.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkOnce.h"
#include "include/private/base/SkPoint_impl.h"
#include "include/private/base/SkTArray.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/base/SkRandom.h"
#include "src/core/SkMatrixPriv.h"
#include "src/gpu/BufferWriter.h"
#include "src/gpu/ResourceKey.h"
#include "src/gpu/ganesh/GrAppliedClip.h"
#include "src/gpu/ganesh/GrBuffer.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrDefaultGeoProcFactory.h"
#include "src/gpu/ganesh/GrDrawOpTest.h"
#include "src/gpu/ganesh/GrGeometryProcessor.h"
#include "src/gpu/ganesh/GrMeshDrawTarget.h"
#include "src/gpu/ganesh/GrOpFlushState.h"
#include "src/gpu/ganesh/GrPaint.h"
#include "src/gpu/ganesh/GrProcessorAnalysis.h"
#include "src/gpu/ganesh/GrProcessorSet.h"
#include "src/gpu/ganesh/GrProgramInfo.h"
#include "src/gpu/ganesh/GrRecordingContextPriv.h"
#include "src/gpu/ganesh/GrResourceProvider.h"
#include "src/gpu/ganesh/GrSimpleMesh.h"
#include "src/gpu/ganesh/GrTestUtils.h"
#include "src/gpu/ganesh/geometry/GrQuad.h"
#include "src/gpu/ganesh/ops/FillRectOp.h"
#include "src/gpu/ganesh/ops/GrMeshDrawOp.h"
#include "src/gpu/ganesh/ops/GrSimpleMeshDrawOpHelper.h"
#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <utility>
class GrDstProxyView;
class GrGpuBuffer;
class GrSurfaceProxyView;
class SkArenaAlloc;
enum class GrXferBarrierFlags;
namespace skgpu::ganesh {
class SurfaceDrawContext;
}
usingnamespaceskia_private;
namespace skgpu::ganesh::StrokeRectOp {
namespace {
inline bool allowed_stroke(const GrCaps* caps, const SkStrokeRec& stroke, GrAA aa, bool* isMiter) { … }
void init_nonaa_stroke_rect_strip(SkPoint verts[10], const SkRect& rect, SkScalar width) { … }
class NonAAStrokeRectOp final : public GrMeshDrawOp { … };
SKGPU_DECLARE_STATIC_UNIQUE_KEY(gMiterIndexBufferKey);
SKGPU_DECLARE_STATIC_UNIQUE_KEY(gBevelIndexBufferKey);
bool stroke_dev_half_size_supported(SkVector devHalfStrokeSize) { … }
bool compute_aa_rects(const GrCaps& caps,
SkRect* devOutside,
SkRect* devOutsideAssist,
SkRect* devInside,
bool* isDegenerate,
const SkMatrix& viewMatrix,
const SkRect& rect,
SkScalar strokeWidth,
bool miterStroke,
SkVector* devHalfStrokeSize) { … }
GrGeometryProcessor* create_aa_stroke_rect_gp(SkArenaAlloc* arena,
bool usesMSAASurface,
bool tweakAlphaForCoverage,
const SkMatrix& viewMatrix,
bool usesLocalCoords,
bool wideColor) { … }
class AAStrokeRectOp final : public GrMeshDrawOp { … };
void AAStrokeRectOp::onCreateProgramInfo(const GrCaps* caps,
SkArenaAlloc* arena,
const GrSurfaceProxyView& writeView,
bool usesMSAASurface,
GrAppliedClip&& appliedClip,
const GrDstProxyView& dstProxyView,
GrXferBarrierFlags renderPassXferBarriers,
GrLoadOp colorLoadOp) { … }
void AAStrokeRectOp::onPrepareDraws(GrMeshDrawTarget* target) { … }
void AAStrokeRectOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) { … }
sk_sp<const GrGpuBuffer> AAStrokeRectOp::GetIndexBuffer(GrResourceProvider* resourceProvider,
bool miterStroke) { … }
GrOp::CombineResult AAStrokeRectOp::onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps)
{ … }
void AAStrokeRectOp::generateAAStrokeRectGeometry(VertexWriter& vertices,
const SkPMColor4f& color,
bool wideColor,
const SkRect& devOutside,
const SkRect& devOutsideAssist,
const SkRect& devInside,
bool miterStroke,
bool degenerate,
const SkVector& devHalfStrokeSize,
bool usesMSAASurface) const { … }
}
GrOp::Owner Make(GrRecordingContext* context,
GrPaint&& paint,
GrAAType aaType,
const SkMatrix& viewMatrix,
const SkRect& rect,
const SkStrokeRec& stroke) { … }
GrOp::Owner MakeNested(GrRecordingContext* context,
GrPaint&& paint,
const SkMatrix& viewMatrix,
const SkRect rects[2]) { … }
}
#if defined(GPU_TEST_UTILS)
GR_DRAW_OP_TEST_DEFINE(NonAAStrokeRectOp) {
SkMatrix viewMatrix = GrTest::TestMatrix(random);
SkRect rect = GrTest::TestRect(random);
SkScalar strokeWidth = random->nextBool() ? 0.0f : 2.0f;
SkPaint strokePaint;
strokePaint.setStrokeWidth(strokeWidth);
strokePaint.setStyle(SkPaint::kStroke_Style);
strokePaint.setStrokeJoin(SkPaint::kMiter_Join);
SkStrokeRec strokeRec(strokePaint);
GrAAType aaType = GrAAType::kNone;
if (numSamples > 1) {
aaType = random->nextBool() ? GrAAType::kMSAA : GrAAType::kNone;
}
return skgpu::ganesh::StrokeRectOp::NonAAStrokeRectOp::Make(context, std::move(paint),
viewMatrix, rect, strokeRec,
aaType);
}
GR_DRAW_OP_TEST_DEFINE(AAStrokeRectOp) {
bool miterStroke = random->nextBool();
SkRect rect =
random->nextBool() ? SkRect::MakeXYWH(10, 10, 50, 40) : SkRect::MakeXYWH(6, 7, 0, 0);
SkScalar minDim = std::min(rect.width(), rect.height());
SkScalar strokeWidth = random->nextUScalar1() * minDim;
SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
rec.setStrokeStyle(strokeWidth);
rec.setStrokeParams(SkPaint::kButt_Cap,
miterStroke ? SkPaint::kMiter_Join : SkPaint::kBevel_Join, 1.f);
SkMatrix matrix = GrTest::TestMatrixRectStaysRect(random);
return skgpu::ganesh::StrokeRectOp::AAStrokeRectOp::Make(context, std::move(paint), matrix,
rect, rec);
}
#endif