chromium/third_party/skia/src/core/SkBitmapProcState.h

/*
 * Copyright 2007 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkBitmapProcState_DEFINED
#define SkBitmapProcState_DEFINED

#include "include/core/SkColor.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkPoint.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkScalar.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkCPUTypes.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkFixed.h"
#include "src/base/SkArenaAlloc.h"
#include "src/core/SkMatrixPriv.h"

#include <cstddef>
#include <cstdint>

class SkImage_Base;
enum class SkTileMode;

SkFractionalInt;
#define SkScalarToFractionalInt(x)
#define SkFractionalIntToFixed(x)
#define SkFixedToFractionalInt(x)
#define SkFractionalIntToInt(x)

struct SkBitmapProcState {};

/*  Macros for packing and unpacking pairs of 16bit values in a 32bit uint.
    Used to allow access to a stream of uint16_t either one at a time, or
    2 at a time by unpacking a uint32_t
 */
#ifdef SK_CPU_BENDIAN
    #define PACK_TWO_SHORTS
    #define UNPACK_PRIMARY_SHORT
    #define UNPACK_SECONDARY_SHORT
#else
    #define PACK_TWO_SHORTS(pri, sec)
    #define UNPACK_PRIMARY_SHORT(packed)
    #define UNPACK_SECONDARY_SHORT(packed)
#endif

#ifdef SK_DEBUG
    static inline uint32_t pack_two_shorts(U16CPU pri, U16CPU sec) {}
#else
    #define pack_two_shorts
#endif

// Helper class for mapping the middle of pixel (x, y) into SkFractionalInt bitmap space.
// Discussion:
// Overall, this code takes a point in destination space, and uses the center of the pixel
// at (x, y) to determine the sample point in source space. It then adjusts the pixel by different
// amounts based in filtering and tiling.
// This code can be broken into two main cases based on filtering:
// * no filtering (nearest neighbor) - when using nearest neighbor filtering all tile modes reduce
// the sampled by one ulp. If a simple point pt lies precisely on XXX.1/2 then it forced down
// when positive making 1/2 + 1/2 = .999999 instead of 1.0.
// * filtering - in the filtering case, the code calculates the -1/2 shift for starting the
// bilerp kernel. There is a twist; there is a big difference between clamp and the other tile
// modes. In tile and repeat the matrix has been reduced by an additional 1/width and 1/height
// factor. This maps from destination space to [0, 1) (instead of source space) to allow easy
// modulo arithmetic. This means that the -1/2 needed by bilerp is actually 1/2 * 1/width for x
// and 1/2 * 1/height for y. This is what happens when the poorly named fFilterOne{X|Y} is
// divided by two.
class SkBitmapProcStateAutoMapper {};

namespace sktests {
    // f is the value to pack, max is the largest the value can be.
    uint32_t pack_clamp(SkFixed f, unsigned max);
    // As above, but width is the width of the pretend bitmap.
    uint32_t pack_repeat(SkFixed f, unsigned max, size_t width);
    uint32_t pack_mirror(SkFixed f, unsigned max, size_t width);
}

namespace SkOpts {
    // SkBitmapProcState optimized Shader, Sample, or Matrix procs.
    extern void (*S32_alpha_D32_filter_DX)(const SkBitmapProcState&,
                                           const uint32_t* xy, int count, SkPMColor*);
    extern void (*S32_alpha_D32_filter_DXDY)(const SkBitmapProcState&,
                                             const uint32_t* xy, int count, SkPMColor*);

    void Init_BitmapProcState();
}  // namespace SkOpts

#endif