Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  SkRasterPipelineOpContexts.h   Sprache: C

 
/*
 * Copyright 2023 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#ifndef SkRasterPipelineOpContexts_DEFINED
#define SkRasterPipelineOpContexts_DEFINED

#include <algorithm>
#include <cstddef>
#include <cstdint>

namespace SkSL { class TraceHook; }

// The largest number of pixels we handle at a time. We have a separate value for the largest number
// of pixels we handle in the highp pipeline. Many of the context structs in this file are only used
// by stages that have no lowp implementation. They can therefore use the (smaller) highp value to
// save memory in the arena.
inline static constexpr int SkRasterPipeline_kMaxStride = 16;
inline static constexpr int SkRasterPipeline_kMaxStride_highp = 16;

// How much space to allocate for each MemoryCtx scratch buffer, as part of tail-pixel handling.
inline static constexpr size_t SkRasterPipeline_MaxScratchPerPatch =
        std::max(SkRasterPipeline_kMaxStride_highp * 16,  // 16 == largest highp bpp (RGBA_F32)
                 SkRasterPipeline_kMaxStride * 4);        // 4 == largest lowp bpp (RGBA_8888)

// These structs hold the context data for many of the Raster Pipeline ops.
struct SkRasterPipeline_MemoryCtx {
    void* pixels;
    int   stride;
};

// Raster Pipeline typically processes N (4, 8, 16) pixels at a time, in SIMT fashion. If the
// number of pixels in a row isn't evenly divisible by N, there will be leftover pixels; this is
// called the "tail". To avoid reading or writing past the end of any source or destination buffers
// when we reach the tail:
//
//   1) Source buffers have their tail contents copied to a scratch buffer that is at least N wide.
//      In practice, each scratch buffer uses SkRasterPipeline_MaxScratchPerPatch bytes.
//   2) Each MemoryCtx in the pipeline is patched, such that access to them (at the current scanline
//      and x-offset) will land in the scratch buffer.
//   3) Pipeline is run as normal (with all memory access happening safely in the scratch buffers).
//   4) Destination buffers have their tail contents copied back from the scratch buffer.
//   5) Each MemoryCtx is "un-patched".
//
// To do all of this, the pipeline creates a MemoryCtxPatch for each unique MemoryCtx referenced by
// the pipeline.
struct SkRasterPipeline_MemoryCtxInfo {
    SkRasterPipeline_MemoryCtx* context;

    int bytesPerPixel;
    bool load;
    bool store;
};

struct SkRasterPipeline_MemoryCtxPatch {
    SkRasterPipeline_MemoryCtxInfo info;

    void* backup;  // Remembers context->pixels so we can restore it
    std::byte scratch[SkRasterPipeline_MaxScratchPerPatch];
};

struct SkRasterPipeline_GatherCtx {
    const void* pixels;
    int         stride;
    float       width;
    float       height;
    float       weights[16];  // for bicubic and bicubic_clamp_8888
    // Controls whether pixel i-1 or i is selected when floating point sample position is exactly i.
    bool        roundDownAtInteger = false;
};

// State shared by save_xy, accumulate, and bilinear_* / bicubic_*.
struct SkRasterPipeline_SamplerCtx {
    float      x[SkRasterPipeline_kMaxStride_highp];
    float      y[SkRasterPipeline_kMaxStride_highp];
    float     fx[SkRasterPipeline_kMaxStride_highp];
    float     fy[SkRasterPipeline_kMaxStride_highp];
    float scalex[SkRasterPipeline_kMaxStride_highp];
    float scaley[SkRasterPipeline_kMaxStride_highp];

    // for bicubic_[np][13][xy]
    float weights[16];
    float wx[4][SkRasterPipeline_kMaxStride_highp];
    float wy[4][SkRasterPipeline_kMaxStride_highp];
};

struct SkRasterPipeline_TileCtx {
    float scale;
    float invScale; // cache of 1/scale
    // When in the reflection portion of mirror tiling we need to snap the opposite direction
    // at integer sample points than when in the forward direction. This controls which way we bias
    // in the reflection. It should be 1 if SkRasterPipeline_GatherCtx::roundDownAtInteger is true
    // and otherwise -1.
    int   mirrorBiasDir = -1;
};

struct SkRasterPipeline_DecalTileCtx {
    uint32_t mask[SkRasterPipeline_kMaxStride];
    float    limit_x;
    float    limit_y;
    // These control which edge of the interval is included (i.e. closed interval at 0 or at limit).
    // They should be set to limit_x and limit_y if SkRasterPipeline_GatherCtx::roundDownAtInteger
    // is true and otherwise zero.
    float    inclusiveEdge_x = 0;
    float    inclusiveEdge_y = 0;
};

enum class SkPerlinNoiseShaderType;

struct SkRasterPipeline_PerlinNoiseCtx {
    SkPerlinNoiseShaderType noiseType;
    float baseFrequencyX, baseFrequencyY;
    float stitchDataInX, stitchDataInY;
    bool stitching;
    int numOctaves;
    const uint8_t* latticeSelector;  // [256 values]
    const uint16_t* noiseData;       // [4 channels][256 elements][vector of 2]
};

// State used by mipmap_linear_*
struct SkRasterPipeline_MipmapCtx {
    // Original coords, saved before the base level logic
    float x[SkRasterPipeline_kMaxStride_highp];
    float y[SkRasterPipeline_kMaxStride_highp];

    // Base level color
    float r[SkRasterPipeline_kMaxStride_highp];
    float g[SkRasterPipeline_kMaxStride_highp];
    float b[SkRasterPipeline_kMaxStride_highp];
    float a[SkRasterPipeline_kMaxStride_highp];

    // Scale factors to transform base level coords to lower level coords
    float scaleX;
    float scaleY;

    float lowerWeight;
};

struct SkRasterPipeline_CoordClampCtx {
    float min_x, min_y;
    float max_x, max_y;
};

struct SkRasterPipeline_CallbackCtx {
    void (*fn)(SkRasterPipeline_CallbackCtx* self,
               int active_pixels /*<= SkRasterPipeline_kMaxStride_highp*/);

    // When called, fn() will have our active pixels available in rgba.
    // When fn() returns, the pipeline will read back those active pixels from read_from.
    float rgba[4*SkRasterPipeline_kMaxStride_highp];
    float* read_from = rgba;
};

// state shared by stack_checkpoint and stack_rewind
struct SkRasterPipelineStage;

struct SkRasterPipeline_RewindCtx {
    float  r[SkRasterPipeline_kMaxStride_highp];
    float  g[SkRasterPipeline_kMaxStride_highp];
    float  b[SkRasterPipeline_kMaxStride_highp];
    float  a[SkRasterPipeline_kMaxStride_highp];
    float dr[SkRasterPipeline_kMaxStride_highp];
    float dg[SkRasterPipeline_kMaxStride_highp];
    float db[SkRasterPipeline_kMaxStride_highp];
    float da[SkRasterPipeline_kMaxStride_highp];
    std::byte* base;
    SkRasterPipelineStage* stage;
};

struct SkRasterPipeline_GradientCtx {
    size_t stopCount;
    float* fs[4];
    float* bs[4];
    float* ts;
};

struct SkRasterPipeline_EvenlySpaced2StopGradientCtx {
    float f[4];
    float b[4];
};

struct SkRasterPipeline_2PtConicalCtx {
    uint32_t fMask[SkRasterPipeline_kMaxStride_highp];
    float    fP0,
             fP1;
};

struct SkRasterPipeline_UniformColorCtx {
    float r,g,b,a;
    uint16_t rgba[4];  // [0,255] in a 16-bit lane.
};

struct SkRasterPipeline_EmbossCtx {
    SkRasterPipeline_MemoryCtx mul,
                               add;
};

struct SkRasterPipeline_TablesCtx {
    const uint8_t *r, *g, *b, *a;
};

using SkRPOffset = uint32_t;

struct SkRasterPipeline_InitLaneMasksCtx {
    uint8_t* tail;
};

struct SkRasterPipeline_ConstantCtx {
    int32_t value;
    SkRPOffset dst;
};

struct SkRasterPipeline_UniformCtx {
    int32_t* dst;
    const int32_t* src;
};

struct SkRasterPipeline_BinaryOpCtx {
    SkRPOffset dst;
    SkRPOffset src;
};

struct SkRasterPipeline_TernaryOpCtx {
    SkRPOffset dst;
    SkRPOffset delta;
};

struct SkRasterPipeline_MatrixMultiplyCtx {
    SkRPOffset dst;
    uint8_t leftColumns, leftRows, rightColumns, rightRows;
};

struct SkRasterPipeline_SwizzleCtx {
    // If we are processing more than 16 pixels at a time, an 8-bit offset won't be sufficient and
    // `offsets` will need to use uint16_t (or dial down the premultiplication).
    static_assert(SkRasterPipeline_kMaxStride_highp <= 16);

    SkRPOffset dst;
    uint8_t offsets[4];  // values must be byte offsets (4 * highp-stride * component-index)
};

struct SkRasterPipeline_ShuffleCtx {
    int32_t* ptr;
    int count;
    uint16_t offsets[16];  // values must be byte offsets (4 * highp-stride * component-index)
};

struct SkRasterPipeline_SwizzleCopyCtx {
    int32_t* dst;
    const int32_t* src;   // src values must _not_ overlap dst values
    uint16_t offsets[4];  // values must be byte offsets (4 * highp-stride * component-index)
};

struct SkRasterPipeline_CopyIndirectCtx {
    int32_t* dst;
    const int32_t* src;
    const uint32_t *indirectOffset;  // this applies to `src` or `dst` based on the op
    uint32_t indirectLimit;          // the indirect offset is clamped to this upper bound
    uint32_t slots;                  // the number of slots to copy
};

struct SkRasterPipeline_SwizzleCopyIndirectCtx : public SkRasterPipeline_CopyIndirectCtx {
    uint16_t offsets[4];  // values must be byte offsets (4 * highp-stride * component-index)
};

struct SkRasterPipeline_BranchCtx {
    int offset;  // contains the label ID during compilation, and the program offset when compiled
};

struct SkRasterPipeline_BranchIfAllLanesActiveCtx : public SkRasterPipeline_BranchCtx {
    uint8_t* tail = nullptr;  // lanes past the tail are _never_ active, so we need to exclude them
};

struct SkRasterPipeline_BranchIfEqualCtx : public SkRasterPipeline_BranchCtx {
    int value;
    const int* ptr;
};

struct SkRasterPipeline_CaseOpCtx {
    int expectedValue;
    SkRPOffset offset;  // points to a pair of adjacent I32s: {I32 actualValue, I32 defaultMask}
};

struct SkRasterPipeline_TraceFuncCtx {
    const int* traceMask;
    SkSL::TraceHook* traceHook;
    int funcIdx;
};

struct SkRasterPipeline_TraceScopeCtx {
    const int* traceMask;
    SkSL::TraceHook* traceHook;
    int delta;
};

struct SkRasterPipeline_TraceLineCtx {
    const int* traceMask;
    SkSL::TraceHook* traceHook;
    int lineNumber;
};

struct SkRasterPipeline_TraceVarCtx {
    const int* traceMask;
    SkSL::TraceHook* traceHook;
    int slotIdx, numSlots;
    const int* data;
    const uint32_t *indirectOffset;  // can be null; if set, an offset applied to `data`
    uint32_t indirectLimit;          // the indirect offset is clamped to this upper bound
};

#endif  // SkRasterPipelineOpContexts_DEFINED

Messung V0.5
C=94 H=93 G=93

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge