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

/*
 * Copyright 2016 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/ShadowRRectOp.h"

#include "include/core/SkBitmap.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkRRect.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkString.h"
#include "include/gpu/ganesh/GrRecordingContext.h"
#include "include/gpu/ganesh/GrTypes.h"
#include "include/private/SkColorData.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkPoint_impl.h"
#include "include/private/base/SkTArray.h"
#include "include/private/base/SkTo.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/core/SkRRectPriv.h"
#include "src/gpu/ResourceKey.h"
#include "src/gpu/ganesh/GrAppliedClip.h"
#include "src/gpu/ganesh/GrBuffer.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/GrPipeline.h"
#include "src/gpu/ganesh/GrProcessorSet.h"
#include "src/gpu/ganesh/GrProgramInfo.h"
#include "src/gpu/ganesh/GrRecordingContextPriv.h"
#include "src/gpu/ganesh/GrSimpleMesh.h"
#include "src/gpu/ganesh/GrSurfaceProxyView.h"
#include "src/gpu/ganesh/GrThreadSafeCache.h"
#include "src/gpu/ganesh/GrUserStencilSettings.h"
#include "src/gpu/ganesh/SkGr.h"
#include "src/gpu/ganesh/effects/GrShadowGeoProc.h"
#include "src/gpu/ganesh/ops/GrMeshDrawOp.h"
#include "src/gpu/ganesh/ops/GrSimpleMeshDrawOpHelper.h"

#if defined(GPU_TEST_UTILS)
#include "src/base/SkRandom.h"
#include "src/gpu/ganesh/GrDrawOpTest.h"
#include "src/gpu/ganesh/GrTestUtils.h"
#endif

#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <tuple>
#include <utility>

class GrCaps;
class GrDstProxyView;
class SkArenaAlloc;
enum class GrXferBarrierFlags;
namespace skgpu {
enum class Mipmapped : bool;
}
namespace skgpu::ganesh {
class SurfaceDrawContext;
}

usingnamespaceskia_private;

namespace {

///////////////////////////////////////////////////////////////////////////////
// Circle Data
//
// We have two possible cases for geometry for a circle:

// In the case of a normal fill, we draw geometry for the circle as an octagon.
static const uint16_t gFillCircleIndices[] =;

// For stroked circles, we use two nested octagons.
static const uint16_t gStrokeCircleIndices[] =;

static const int kIndicesPerFillCircle =;
static const int kIndicesPerStrokeCircle =;
static const int kVertsPerStrokeCircle =;
static const int kVertsPerFillCircle =;

int circle_type_to_vert_count(bool stroked) {}

int circle_type_to_index_count(bool stroked) {}

const uint16_t* circle_type_to_indices(bool stroked) {}

///////////////////////////////////////////////////////////////////////////////
// RoundRect Data
//
// The geometry for a shadow roundrect is similar to a 9-patch:
//    ____________
//   |_|________|_|
//   | |        | |
//   | |        | |
//   | |        | |
//   |_|________|_|
//   |_|________|_|
//
// However, each corner is rendered as a fan rather than a simple quad, as below. (The diagram
// shows the upper part of the upper left corner. The bottom triangle would similarly be split
// into two triangles.)
//    ________
//   |\  \   |
//   |  \ \  |
//   |    \\ |
//   |      \|
//   --------
//
// The center of the fan handles the curve of the corner. For roundrects where the stroke width
// is greater than the corner radius, the outer triangles blend from the curve to the straight
// sides. Otherwise these triangles will be degenerate.
//
// In the case where the stroke width is greater than the corner radius and the
// blur radius (overstroke), we add additional geometry to mark out the rectangle in the center.
// This rectangle extends the coverage values of the center edges of the 9-patch.
//    ____________
//   |_|________|_|
//   | |\ ____ /| |
//   | | |    | | |
//   | | |____| | |
//   |_|/______\|_|
//   |_|________|_|
//
// For filled rrects we reuse the stroke geometry but add an additional quad to the center.

static const uint16_t gRRectIndices[] =;

// overstroke count
static const int kIndicesPerOverstrokeRRect =;
// simple stroke count skips overstroke indices
static const int kIndicesPerStrokeRRect =;
// fill count adds final quad to stroke count
static const int kIndicesPerFillRRect =;
static const int kVertsPerStrokeRRect =;
static const int kVertsPerOverstrokeRRect =;
static const int kVertsPerFillRRect =;

enum RRectType {};

int rrect_type_to_vert_count(RRectType type) {}

int rrect_type_to_index_count(RRectType type) {}

const uint16_t* rrect_type_to_indices(RRectType type) {}

///////////////////////////////////////////////////////////////////////////////

class ShadowCircularRRectOp final : public GrMeshDrawOp {};

}  // anonymous namespace

///////////////////////////////////////////////////////////////////////////////

namespace skgpu::ganesh::ShadowRRectOp {

static GrSurfaceProxyView create_falloff_texture(GrRecordingContext* rContext) {}

GrOp::Owner Make(GrRecordingContext* context,
                 GrColor color,
                 const SkMatrix& viewMatrix,
                 const SkRRect& rrect,
                 SkScalar blurWidth,
                 SkScalar insetWidth) {}

}  // namespace skgpu::ganesh::ShadowRRectOp

///////////////////////////////////////////////////////////////////////////////

#if defined(GPU_TEST_UTILS)

GR_DRAW_OP_TEST_DEFINE(ShadowRRectOp) {
    // We may choose matrix and inset values that cause the factory to fail. We loop until we find
    // an acceptable combination.
    do {
        // create a similarity matrix
        SkScalar rotate = random->nextSScalar1() * 360.f;
        SkScalar translateX = random->nextSScalar1() * 1000.f;
        SkScalar translateY = random->nextSScalar1() * 1000.f;
        SkScalar scale = random->nextSScalar1() * 100.f;
        SkMatrix viewMatrix;
        viewMatrix.setRotate(rotate);
        viewMatrix.postTranslate(translateX, translateY);
        viewMatrix.postScale(scale, scale);
        SkScalar insetWidth = random->nextSScalar1() * 72.f;
        SkScalar blurWidth = random->nextSScalar1() * 72.f;
        bool isCircle = random->nextBool();
        // This op doesn't use a full GrPaint, just a color.
        GrColor color = paint.getColor4f().toBytes_RGBA();
        if (isCircle) {
            SkRect circle = GrTest::TestSquare(random);
            SkRRect rrect = SkRRect::MakeOval(circle);
            if (auto op = skgpu::ganesh::ShadowRRectOp::Make(
                        context, color, viewMatrix, rrect, blurWidth, insetWidth)) {
                return op;
            }
        } else {
            SkRRect rrect;
            do {
                // This may return a rrect with elliptical corners, which will cause an assert.
                rrect = GrTest::TestRRectSimple(random);
            } while (!SkRRectPriv::IsSimpleCircular(rrect));
            if (auto op = skgpu::ganesh::ShadowRRectOp::Make(
                        context, color, viewMatrix, rrect, blurWidth, insetWidth)) {
                return op;
            }
        }
    } while (true);
}

#endif // defined(GPU_TEST_UTILS)