chromium/third_party/skia/src/gpu/ganesh/effects/GrDistanceFieldGeoProc.cpp

/*
 * Copyright 2013 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/effects/GrDistanceFieldGeoProc.h"

#include "include/core/SkSamplingOptions.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkMath.h"
#include "include/private/base/SkTo.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/base/SkRandom.h"
#include "src/core/SkDistanceFieldGen.h"
#include "src/core/SkSLTypeShared.h"
#include "src/gpu/KeyBuilder.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrShaderCaps.h"
#include "src/gpu/ganesh/GrShaderVar.h"
#include "src/gpu/ganesh/GrSurfaceProxy.h"
#include "src/gpu/ganesh/GrSurfaceProxyView.h"
#include "src/gpu/ganesh/GrTestUtils.h"
#include "src/gpu/ganesh/effects/GrAtlasedShaderHelpers.h"
#include "src/gpu/ganesh/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/ganesh/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/ganesh/glsl/GrGLSLUniformHandler.h"
#include "src/gpu/ganesh/glsl/GrGLSLVarying.h"
#include "src/gpu/ganesh/glsl/GrGLSLVertexGeoBuilder.h"

#include <algorithm>

#if !defined(SK_DISABLE_SDF_TEXT)

// Assuming a radius of a little less than the diagonal of the fragment
#define SK_DistanceFieldAAFactor

class GrDistanceFieldA8TextGeoProc::Impl : public ProgramImpl {};

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

GrDistanceFieldA8TextGeoProc::GrDistanceFieldA8TextGeoProc(const GrShaderCaps& caps,
                                                           const GrSurfaceProxyView* views,
                                                           int numViews,
                                                           GrSamplerState params,
#ifdef SK_GAMMA_APPLY_TO_A8
                                                           float distanceAdjust,
#endif
                                                           uint32_t flags,
                                                           const SkMatrix& localMatrix)
        :{}

void GrDistanceFieldA8TextGeoProc::addNewViews(const GrSurfaceProxyView* views,
                                               int numViews,
                                               GrSamplerState params) {}

void GrDistanceFieldA8TextGeoProc::addToKey(const GrShaderCaps& caps,
                                            skgpu::KeyBuilder* b) const {}

std::unique_ptr<GrGeometryProcessor::ProgramImpl> GrDistanceFieldA8TextGeoProc::makeProgramImpl(
        const GrShaderCaps&) const {}

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

GR_DEFINE_GEOMETRY_PROCESSOR_TEST()

#if defined(GPU_TEST_UTILS)
GrGeometryProcessor* GrDistanceFieldA8TextGeoProc::TestCreate(GrProcessorTestData* d) {
    auto [view, ct, at] = d->randomAlphaOnlyView();

    GrSamplerState::WrapMode wrapModes[2];
    GrTest::TestWrapModes(d->fRandom, wrapModes);
    GrSamplerState samplerState(wrapModes, d->fRandom->nextBool()
                                                   ? GrSamplerState::Filter::kLinear
                                                   : GrSamplerState::Filter::kNearest);

    uint32_t flags = 0;
    flags |= d->fRandom->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0;
    if (flags & kSimilarity_DistanceFieldEffectFlag) {
        flags |= d->fRandom->nextBool() ? kScaleOnly_DistanceFieldEffectFlag : 0;
    }
    SkMatrix localMatrix = GrTest::TestMatrix(d->fRandom);
#ifdef SK_GAMMA_APPLY_TO_A8
    float lum = d->fRandom->nextF();
#endif
    return GrDistanceFieldA8TextGeoProc::Make(d->allocator(), *d->caps()->shaderCaps(),
                                              &view, 1,
                                              samplerState,
#ifdef SK_GAMMA_APPLY_TO_A8
                                              lum,
#endif
                                              flags, localMatrix);
}
#endif

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

class GrDistanceFieldPathGeoProc::Impl : public ProgramImpl {};

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

GrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc(const GrShaderCaps& caps,
                                                       const GrSurfaceProxyView* views,
                                                       int numViews,
                                                       GrSamplerState params,
                                                       const SkMatrix& localMatrix,
                                                       uint32_t flags)
        :{}

void GrDistanceFieldPathGeoProc::addNewViews(const GrSurfaceProxyView* views,
                                             int numViews,
                                             GrSamplerState params) {}

void GrDistanceFieldPathGeoProc::addToKey(const GrShaderCaps& caps,
                                          skgpu::KeyBuilder* b) const {}

std::unique_ptr<GrGeometryProcessor::ProgramImpl> GrDistanceFieldPathGeoProc::makeProgramImpl(
        const GrShaderCaps&) const {}

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

GR_DEFINE_GEOMETRY_PROCESSOR_TEST()

#if defined(GPU_TEST_UTILS)
GrGeometryProcessor* GrDistanceFieldPathGeoProc::TestCreate(GrProcessorTestData* d) {
    auto [view, ct, at] = d->randomAlphaOnlyView();

    GrSamplerState::WrapMode wrapModes[2];
    GrTest::TestWrapModes(d->fRandom, wrapModes);
    GrSamplerState samplerState(wrapModes, d->fRandom->nextBool()
                                                   ? GrSamplerState::Filter::kLinear
                                                   : GrSamplerState::Filter::kNearest);

    uint32_t flags = 0;
    flags |= d->fRandom->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0;
    if (flags & kSimilarity_DistanceFieldEffectFlag) {
        flags |= d->fRandom->nextBool() ? kScaleOnly_DistanceFieldEffectFlag : 0;
    }
    flags |= d->fRandom->nextBool() ? kWideColor_DistanceFieldEffectFlag : 0;
    SkMatrix localMatrix = GrTest::TestMatrix(d->fRandom);
    return GrDistanceFieldPathGeoProc::Make(d->allocator(), *d->caps()->shaderCaps(),
                                            &view, 1,
                                            samplerState,
                                            localMatrix,
                                            flags);
}
#endif


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

class GrDistanceFieldLCDTextGeoProc::Impl : public ProgramImpl {};

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

GrDistanceFieldLCDTextGeoProc::GrDistanceFieldLCDTextGeoProc(const GrShaderCaps& caps,
                                                             const GrSurfaceProxyView* views,
                                                             int numViews,
                                                             GrSamplerState params,
                                                             DistanceAdjust distanceAdjust,
                                                             uint32_t flags,
                                                             const SkMatrix& localMatrix)
        :{}

void GrDistanceFieldLCDTextGeoProc::addNewViews(const GrSurfaceProxyView* views,
                                                int numViews,
                                                GrSamplerState params) {}

void GrDistanceFieldLCDTextGeoProc::addToKey(const GrShaderCaps& caps,
                                             skgpu::KeyBuilder* b) const {}

std::unique_ptr<GrGeometryProcessor::ProgramImpl> GrDistanceFieldLCDTextGeoProc::makeProgramImpl(
        const GrShaderCaps&) const {}

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

GR_DEFINE_GEOMETRY_PROCESSOR_TEST()

#if defined(GPU_TEST_UTILS)
GrGeometryProcessor* GrDistanceFieldLCDTextGeoProc::TestCreate(GrProcessorTestData* d) {
    auto [view, ct, at] = d->randomView();

    GrSamplerState::WrapMode wrapModes[2];
    GrTest::TestWrapModes(d->fRandom, wrapModes);
    GrSamplerState samplerState(wrapModes, d->fRandom->nextBool()
                                                   ? GrSamplerState::Filter::kLinear
                                                   : GrSamplerState::Filter::kNearest);
    DistanceAdjust wa = { 0.0f, 0.1f, -0.1f };
    uint32_t flags = kUseLCD_DistanceFieldEffectFlag;
    flags |= d->fRandom->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0;
    if (flags & kSimilarity_DistanceFieldEffectFlag) {
        flags |= d->fRandom->nextBool() ? kScaleOnly_DistanceFieldEffectFlag : 0;
    }
    flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0;
    SkMatrix localMatrix = GrTest::TestMatrix(d->fRandom);

    return GrDistanceFieldLCDTextGeoProc::Make(d->allocator(), *d->caps()->shaderCaps(), &view,
                                               1, samplerState, wa, flags, localMatrix);
}
#endif

#endif // !defined(SK_DISABLE_SDF_TEXT)