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

/*
 * Copyright 2017 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/TextureOp.h"

#include "include/core/SkAlphaType.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkColor.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/gpu/GpuTypes.h"
#include "include/gpu/ganesh/GrBackendSurface.h"
#include "include/gpu/ganesh/GrRecordingContext.h"
#include "include/gpu/ganesh/GrTypes.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkTo.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/base/SkArenaAlloc.h"
#include "src/base/SkVx.h"
#include "src/core/SkRectPriv.h"
#include "src/core/SkTraceEvent.h"
#include "src/gpu/SkBackingFit.h"
#include "src/gpu/Swizzle.h"
#include "src/gpu/ganesh/GrAppliedClip.h"
#include "src/gpu/ganesh/GrBuffer.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrColorSpaceXform.h"
#include "src/gpu/ganesh/GrDrawOpTest.h"
#include "src/gpu/ganesh/GrFragmentProcessor.h"
#include "src/gpu/ganesh/GrGeometryProcessor.h"
#include "src/gpu/ganesh/GrMeshDrawTarget.h"
#include "src/gpu/ganesh/GrOpFlushState.h"
#include "src/gpu/ganesh/GrOpsTypes.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/GrResourceProvider.h"
#include "src/gpu/ganesh/GrSurfaceProxy.h"
#include "src/gpu/ganesh/GrSurfaceProxyView.h"
#include "src/gpu/ganesh/GrTextureProxy.h"
#include "src/gpu/ganesh/GrXferProcessor.h"
#include "src/gpu/ganesh/SkGr.h"
#include "src/gpu/ganesh/SurfaceDrawContext.h"
#include "src/gpu/ganesh/effects/GrBlendFragmentProcessor.h"
#include "src/gpu/ganesh/effects/GrTextureEffect.h"
#include "src/gpu/ganesh/geometry/GrQuad.h"
#include "src/gpu/ganesh/geometry/GrQuadBuffer.h"
#include "src/gpu/ganesh/geometry/GrQuadUtils.h"
#include "src/gpu/ganesh/geometry/GrRect.h"
#include "src/gpu/ganesh/ops/FillRectOp.h"
#include "src/gpu/ganesh/ops/GrMeshDrawOp.h"
#include "src/gpu/ganesh/ops/GrSimpleMeshDrawOpHelper.h"
#include "src/gpu/ganesh/ops/QuadPerEdgeAA.h"

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

#include <algorithm>
#include <cmath>
#include <cstring>
#include <limits>
#include <memory>
#include <new>
#include <utility>

class GrDstProxyView;

usingnamespaceskgpu::ganesh;

namespace {

Subset;
VertexSpec;
ColorType;

// Extracts lengths of vertical and horizontal edges of axis-aligned quad. "width" is the edge
// between v0 and v2 (or v1 and v3), "height" is the edge between v0 and v1 (or v2 and v3).
SkSize axis_aligned_quad_size(const GrQuad& quad) {}

// Describes function for normalizing src coords: [x * iw, y * ih + yOffset] can represent
// regular and rectangular textures, w/ or w/o origin correction.
struct NormalizationParams {};
NormalizationParams proxy_normalization_params(const GrSurfaceProxy* proxy,
                                               GrSurfaceOrigin origin) {}

// Normalize the subset. If 'subsetRect' is null, it is assumed no subset constraint is desired,
// so a sufficiently large rect is returned even if the quad ends up batched with an op that uses
// subsets overall. When there is a subset it will be inset based on the filter mode. Normalization
// and y-flipping are applied as indicated by NormalizationParams.
SkRect normalize_and_inset_subset(GrSamplerState::Filter filter,
                                  const NormalizationParams& params,
                                  const SkRect* subsetRect) {}

// Normalizes logical src coords and corrects for origin
void normalize_src_quad(const NormalizationParams& params,
                        GrQuad* srcQuad) {}

// Count the number of proxy runs in the entry set. This usually is already computed by
// SkGpuDevice, but when the BatchLengthLimiter chops the set up it must determine a new proxy count
// for each split.
int proxy_run_count(const GrTextureSetEntry set[], int count) {}

bool safe_to_ignore_subset_rect(GrAAType aaType, GrSamplerState::Filter filter,
                                const DrawQuad& quad, const SkRect& subsetRect) {}

/**
 * Op that implements TextureOp::Make. It draws textured quads. Each quad can modulate against a
 * the texture by color. The blend with the destination is always src-over. The edges are non-AA.
 */
class TextureOpImpl final : public GrMeshDrawOp {};

}  // anonymous namespace

namespace skgpu::ganesh {

#if defined(GPU_TEST_UTILS)
uint32_t TextureOp::ClassID() {
    return TextureOpImpl::ClassID();
}
#endif

std::tuple<bool /* filter */, bool /* mipmap */> FilterAndMipmapHaveNoEffect(
        const GrQuad& srcQuad, const GrQuad& dstQuad) {}

GrOp::Owner TextureOp::Make(GrRecordingContext* context,
                            GrSurfaceProxyView proxyView,
                            SkAlphaType alphaType,
                            sk_sp<GrColorSpaceXform> textureXform,
                            GrSamplerState::Filter filter,
                            GrSamplerState::MipmapMode mm,
                            const SkPMColor4f& color,
                            Saturate saturate,
                            SkBlendMode blendMode,
                            GrAAType aaType,
                            DrawQuad* quad,
                            const SkRect* subset) {}

// A helper class that assists in breaking up bulk API quad draws into manageable chunks.
class TextureOp::BatchSizeLimiter {};

// Greedily clump quad draws together until the index buffer limit is exceeded.
void TextureOp::AddTextureSetOps(ganesh::SurfaceDrawContext* sdc,
                                 const GrClip* clip,
                                 GrRecordingContext* context,
                                 GrTextureSetEntry set[],
                                 int cnt,
                                 int proxyRunCnt,
                                 GrSamplerState::Filter filter,
                                 GrSamplerState::MipmapMode mm,
                                 Saturate saturate,
                                 SkBlendMode blendMode,
                                 GrAAType aaType,
                                 SkCanvas::SrcRectConstraint constraint,
                                 const SkMatrix& viewMatrix,
                                 sk_sp<GrColorSpaceXform> textureColorSpaceXform) {}

} // namespace skgpu::ganesh

#if defined(GPU_TEST_UTILS)
GR_DRAW_OP_TEST_DEFINE(TextureOpImpl) {
    SkISize dims;
    dims.fHeight = random->nextULessThan(90) + 10;
    dims.fWidth = random->nextULessThan(90) + 10;
    auto origin = random->nextBool() ? kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin;
    skgpu::Mipmapped mipmapped =
            random->nextBool() ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo;
    SkBackingFit fit = SkBackingFit::kExact;
    if (mipmapped == skgpu::Mipmapped::kNo) {
        fit = random->nextBool() ? SkBackingFit::kApprox : SkBackingFit::kExact;
    }
    const GrBackendFormat format =
            context->priv().caps()->getDefaultBackendFormat(GrColorType::kRGBA_8888,
                                                            GrRenderable::kNo);
    GrProxyProvider* proxyProvider = context->priv().proxyProvider();
    sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(format,
                                                             dims,
                                                             GrRenderable::kNo,
                                                             1,
                                                             mipmapped,
                                                             fit,
                                                             skgpu::Budgeted::kNo,
                                                             GrProtected::kNo,
                                                             /*label=*/"TextureOp",
                                                             GrInternalSurfaceFlags::kNone);

    SkRect rect = GrTest::TestRect(random);
    SkRect srcRect;
    srcRect.fLeft = random->nextRangeScalar(0.f, proxy->width() / 2.f);
    srcRect.fRight = random->nextRangeScalar(0.f, proxy->width()) + proxy->width() / 2.f;
    srcRect.fTop = random->nextRangeScalar(0.f, proxy->height() / 2.f);
    srcRect.fBottom = random->nextRangeScalar(0.f, proxy->height()) + proxy->height() / 2.f;
    SkMatrix viewMatrix = GrTest::TestMatrixPreservesRightAngles(random);
    SkPMColor4f color = SkPMColor4f::FromBytes_RGBA(SkColorToPremulGrColor(random->nextU()));
    GrSamplerState::Filter filter = (GrSamplerState::Filter)random->nextULessThan(
            static_cast<uint32_t>(GrSamplerState::Filter::kLast) + 1);
    GrSamplerState::MipmapMode mm = GrSamplerState::MipmapMode::kNone;
    if (mipmapped == skgpu::Mipmapped::kYes) {
        mm = (GrSamplerState::MipmapMode)random->nextULessThan(
                static_cast<uint32_t>(GrSamplerState::MipmapMode::kLast) + 1);
    }

    auto texXform = GrTest::TestColorXform(random);
    GrAAType aaType = GrAAType::kNone;
    if (random->nextBool()) {
        aaType = (numSamples > 1) ? GrAAType::kMSAA : GrAAType::kCoverage;
    }
    GrQuadAAFlags aaFlags = GrQuadAAFlags::kNone;
    aaFlags |= random->nextBool() ? GrQuadAAFlags::kLeft : GrQuadAAFlags::kNone;
    aaFlags |= random->nextBool() ? GrQuadAAFlags::kTop : GrQuadAAFlags::kNone;
    aaFlags |= random->nextBool() ? GrQuadAAFlags::kRight : GrQuadAAFlags::kNone;
    aaFlags |= random->nextBool() ? GrQuadAAFlags::kBottom : GrQuadAAFlags::kNone;
    bool useSubset = random->nextBool();
    auto saturate = random->nextBool() ? TextureOp::Saturate::kYes
                                       : TextureOp::Saturate::kNo;
    GrSurfaceProxyView proxyView(
            std::move(proxy), origin,
            context->priv().caps()->getReadSwizzle(format, GrColorType::kRGBA_8888));
    auto alphaType = static_cast<SkAlphaType>(
            random->nextRangeU(kUnknown_SkAlphaType + 1, kLastEnum_SkAlphaType));

    DrawQuad quad = {GrQuad::MakeFromRect(rect, viewMatrix), GrQuad(srcRect), aaFlags};
    return TextureOp::Make(context, std::move(proxyView), alphaType,
                           std::move(texXform), filter, mm, color, saturate,
                           SkBlendMode::kSrcOver, aaType, &quad,
                           useSubset ? &srcRect : nullptr);
}

#endif // defined(GPU_TEST_UTILS)