chromium/third_party/skia/src/gpu/ganesh/ops/StrokeRectOp.cpp

/*
 * Copyright 2018 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#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 {

// This emits line primitives for hairlines, so only support hairlines if allowed by caps. Otherwise
// we support all hairlines, bevels, and miters, but not round joins. Also, check whether the miter
// limit makes a miter join effectively beveled. If the miter is effectively beveled, it is only
// supported when using an AA stroke.
inline bool allowed_stroke(const GrCaps* caps, const SkStrokeRec& stroke, GrAA aa, bool* isMiter) {}


///////////////////////////////////////////////////////////////////////////////////////////////////
// Non-AA Stroking
///////////////////////////////////////////////////////////////////////////////////////////////////

/*  create a triangle strip that strokes the specified rect. There are 8
    unique vertices, but we repeat the last 2 to close up. Alternatively we
    could use an indices array, and then only send 8 verts, but not sure that
    would be faster.
    */
void init_nonaa_stroke_rect_strip(SkPoint verts[10], const SkRect& rect, SkScalar width) {}

class NonAAStrokeRectOp final : public GrMeshDrawOp {};

///////////////////////////////////////////////////////////////////////////////////////////////////
// AA Stroking
///////////////////////////////////////////////////////////////////////////////////////////////////

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 {}

}  // anonymous namespace

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]) {}

} // namespace skgpu::ganesh::StrokeRectOp

#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();

    // Create either a empty rect or a non-empty rect.
    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