#include "src/gpu/ganesh/ops/DrawAtlasOp.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkRSXform.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkString.h"
#include "include/private/SkColorData.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkMath.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/base/SkRandom.h"
#include "src/base/SkSafeMath.h"
#include "src/core/SkMatrixPriv.h"
#include "src/core/SkRectPriv.h"
#include "src/gpu/ganesh/GrAppliedClip.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrColor.h"
#include "src/gpu/ganesh/GrDefaultGeoProcFactory.h"
#include "src/gpu/ganesh/GrDrawOpTest.h"
#include "src/gpu/ganesh/GrGeometryProcessor.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/GrTestUtils.h"
#include "src/gpu/ganesh/SkGr.h"
#include "src/gpu/ganesh/ops/GrDrawOp.h"
#include "src/gpu/ganesh/ops/GrMeshDrawOp.h"
#include "src/gpu/ganesh/ops/GrSimpleMeshDrawOpHelper.h"
#include <cstdint>
#include <cstring>
#include <utility>
class GrDstProxyView;
class GrMeshDrawTarget;
class GrSurfaceProxyView;
class SkArenaAlloc;
enum class GrXferBarrierFlags;
struct GrSimpleMesh;
namespace skgpu::ganesh {
class SurfaceDrawContext;
}
usingnamespaceskia_private;
namespace {
class DrawAtlasOpImpl final : public GrMeshDrawOp { … };
GrGeometryProcessor* make_gp(SkArenaAlloc* arena,
bool hasColors,
const SkPMColor4f& color,
const SkMatrix& viewMatrix) { … }
DrawAtlasOpImpl::DrawAtlasOpImpl(GrProcessorSet* processorSet, const SkPMColor4f& color,
const SkMatrix& viewMatrix, GrAAType aaType, int spriteCount,
const SkRSXform* xforms, const SkRect* rects,
const SkColor* colors)
: … { … }
#if defined(GPU_TEST_UTILS)
SkString DrawAtlasOpImpl::onDumpInfo() const {
SkString string;
for (const auto& geo : fGeoData) {
string.appendf("Color: 0x%08x, Quads: %d\n", geo.fColor.toBytes_RGBA(),
geo.fVerts.size() / 4);
}
string += fHelper.dumpInfo();
return string;
}
#endif
void DrawAtlasOpImpl::onCreateProgramInfo(const GrCaps* caps,
SkArenaAlloc* arena,
const GrSurfaceProxyView& writeView,
bool usesMSAASurface,
GrAppliedClip&& appliedClip,
const GrDstProxyView& dstProxyView,
GrXferBarrierFlags renderPassXferBarriers,
GrLoadOp colorLoadOp) { … }
void DrawAtlasOpImpl::onPrepareDraws(GrMeshDrawTarget* target) { … }
void DrawAtlasOpImpl::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) { … }
GrOp::CombineResult DrawAtlasOpImpl::onCombineIfPossible(GrOp* t,
SkArenaAlloc*,
const GrCaps& caps) { … }
GrDrawOp::FixedFunctionFlags DrawAtlasOpImpl::fixedFunctionFlags() const { … }
GrProcessorSet::Analysis DrawAtlasOpImpl::finalize(const GrCaps& caps,
const GrAppliedClip* clip,
GrClampType clampType) { … }
}
namespace skgpu::ganesh::DrawAtlasOp {
GrOp::Owner Make(GrRecordingContext* context,
GrPaint&& paint,
const SkMatrix& viewMatrix,
GrAAType aaType,
int spriteCount,
const SkRSXform* xforms,
const SkRect* rects,
const SkColor* colors) { … }
}
#if defined(GPU_TEST_UTILS)
static SkRSXform random_xform(SkRandom* random) {
static const SkScalar kMinExtent = -100.f;
static const SkScalar kMaxExtent = 100.f;
static const SkScalar kMinScale = 0.1f;
static const SkScalar kMaxScale = 100.f;
static const SkScalar kMinRotate = -SK_ScalarPI;
static const SkScalar kMaxRotate = SK_ScalarPI;
SkRSXform xform = SkRSXform::MakeFromRadians(random->nextRangeScalar(kMinScale, kMaxScale),
random->nextRangeScalar(kMinRotate, kMaxRotate),
random->nextRangeScalar(kMinExtent, kMaxExtent),
random->nextRangeScalar(kMinExtent, kMaxExtent),
random->nextRangeScalar(kMinExtent, kMaxExtent),
random->nextRangeScalar(kMinExtent, kMaxExtent));
return xform;
}
static SkRect random_texRect(SkRandom* random) {
static const SkScalar kMinCoord = 0.0f;
static const SkScalar kMaxCoord = 1024.f;
SkRect texRect = SkRect::MakeLTRB(random->nextRangeScalar(kMinCoord, kMaxCoord),
random->nextRangeScalar(kMinCoord, kMaxCoord),
random->nextRangeScalar(kMinCoord, kMaxCoord),
random->nextRangeScalar(kMinCoord, kMaxCoord));
texRect.sort();
return texRect;
}
static void randomize_params(uint32_t count, SkRandom* random, TArray<SkRSXform>* xforms,
TArray<SkRect>* texRects, TArray<GrColor>* colors,
bool hasColors) {
for (uint32_t v = 0; v < count; v++) {
xforms->push_back(random_xform(random));
texRects->push_back(random_texRect(random));
if (hasColors) {
colors->push_back(GrTest::RandomColor(random));
}
}
}
GR_DRAW_OP_TEST_DEFINE(DrawAtlasOp) {
uint32_t spriteCount = random->nextRangeU(1, 100);
TArray<SkRSXform> xforms(spriteCount);
TArray<SkRect> texRects(spriteCount);
TArray<GrColor> colors;
bool hasColors = random->nextBool();
randomize_params(spriteCount, random, &xforms, &texRects, &colors, hasColors);
SkMatrix viewMatrix = GrTest::TestMatrix(random);
GrAAType aaType = GrAAType::kNone;
if (numSamples > 1 && random->nextBool()) {
aaType = GrAAType::kMSAA;
}
return skgpu::ganesh::DrawAtlasOp::Make(context,
std::move(paint),
viewMatrix,
aaType,
spriteCount,
xforms.begin(),
texRects.begin(),
hasColors ? colors.begin() : nullptr);
}
#endif