Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkBitmapProcState.h
Go to the documentation of this file.
1/*
2 * Copyright 2007 The Android Open Source Project
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkBitmapProcState_DEFINED
9#define SkBitmapProcState_DEFINED
10
22
23#include <cstddef>
24#include <cstdint>
25
26class SkImage_Base;
27enum class SkTileMode;
28
30#define SkScalarToFractionalInt(x) SkScalarToFixed3232(x)
31#define SkFractionalIntToFixed(x) SkFixed3232ToFixed(x)
32#define SkFixedToFractionalInt(x) SkFixedToFixed3232(x)
33#define SkFractionalIntToInt(x) SkFixed3232ToInt(x)
34
37
38 bool setup(const SkMatrix& inv, SkColor color, const SkSamplingOptions& sampling) {
39 return this->init(inv, color, sampling)
40 && this->chooseProcs();
41 }
42
43 typedef void (*ShaderProc32)(const void* ctx, int x, int y, SkPMColor[], int count);
44
45 typedef void (*MatrixProc)(const SkBitmapProcState&,
46 uint32_t bitmapXY[],
47 int count,
48 int x, int y);
49
50 typedef void (*SampleProc32)(const SkBitmapProcState&,
51 const uint32_t[],
52 int count,
53 SkPMColor colors[]);
54
56
58 SkMatrix fInvMatrix; // This changes based on tile mode.
62 bool fBilerp;
63
67
70
71 uint16_t fAlphaScale; // chooseProcs
72
73 /** Given the byte size of the index buffer to be passed to the matrix proc,
74 return the maximum number of resulting pixels that can be computed
75 (i.e. the number of SkPMColor values to be written by the sample proc).
76 This routine takes into account that filtering and scale-vs-affine
77 affect the amount of buffer space needed.
78
79 Only valid to call after chooseProcs (setContext) has been called. It is
80 safe to call this inside the shader's shadeSpan() method.
81 */
82 int maxCountForBufferSize(size_t bufferSize) const;
83
84 // If a shader proc is present, then the corresponding matrix/sample procs
85 // are ignored
86 ShaderProc32 getShaderProc32() const { return fShaderProc32; }
87
88#ifdef SK_DEBUG
90#else
91 MatrixProc getMatrixProc() const { return fMatrixProc; }
92#endif
93 SampleProc32 getSampleProc32() const { return fSampleProc32; }
94
95private:
96 enum {
97 kBMStateSize = 136 // found by inspection. if too small, we will call new/delete
98 };
100
101 ShaderProc32 fShaderProc32; // chooseProcs
102 // These are used if the shaderproc is nullptr
103 MatrixProc fMatrixProc; // chooseProcs
104 SampleProc32 fSampleProc32; // chooseProcs
105
106 bool init(const SkMatrix& inverse, SkAlpha, const SkSamplingOptions&);
107 bool chooseProcs();
108 MatrixProc chooseMatrixProc(bool trivial_matrix);
109 ShaderProc32 chooseShaderProc32();
110
111 // Return false if we failed to setup for fast translate (e.g. overflow)
112 bool setupForTranslate();
113
114#ifdef SK_DEBUG
115 static void DebugMatrixProc(const SkBitmapProcState&,
116 uint32_t[], int count, int x, int y);
117#endif
118};
119
120/* Macros for packing and unpacking pairs of 16bit values in a 32bit uint.
121 Used to allow access to a stream of uint16_t either one at a time, or
122 2 at a time by unpacking a uint32_t
123 */
124#ifdef SK_CPU_BENDIAN
125 #define PACK_TWO_SHORTS(pri, sec) ((pri) << 16 | (sec))
126 #define UNPACK_PRIMARY_SHORT(packed) ((uint32_t)(packed) >> 16)
127 #define UNPACK_SECONDARY_SHORT(packed) ((packed) & 0xFFFF)
128#else
129 #define PACK_TWO_SHORTS(pri, sec) ((pri) | ((sec) << 16))
130 #define UNPACK_PRIMARY_SHORT(packed) ((packed) & 0xFFFF)
131 #define UNPACK_SECONDARY_SHORT(packed) ((uint32_t)(packed) >> 16)
132#endif
133
134#ifdef SK_DEBUG
135 static inline uint32_t pack_two_shorts(U16CPU pri, U16CPU sec) {
136 SkASSERT((uint16_t)pri == pri);
137 SkASSERT((uint16_t)sec == sec);
138 return PACK_TWO_SHORTS(pri, sec);
139 }
140#else
141 #define pack_two_shorts(pri, sec) PACK_TWO_SHORTS(pri, sec)
142#endif
143
144// Helper class for mapping the middle of pixel (x, y) into SkFractionalInt bitmap space.
145// Discussion:
146// Overall, this code takes a point in destination space, and uses the center of the pixel
147// at (x, y) to determine the sample point in source space. It then adjusts the pixel by different
148// amounts based in filtering and tiling.
149// This code can be broken into two main cases based on filtering:
150// * no filtering (nearest neighbor) - when using nearest neighbor filtering all tile modes reduce
151// the sampled by one ulp. If a simple point pt lies precisely on XXX.1/2 then it forced down
152// when positive making 1/2 + 1/2 = .999999 instead of 1.0.
153// * filtering - in the filtering case, the code calculates the -1/2 shift for starting the
154// bilerp kernel. There is a twist; there is a big difference between clamp and the other tile
155// modes. In tile and repeat the matrix has been reduced by an additional 1/width and 1/height
156// factor. This maps from destination space to [0, 1) (instead of source space) to allow easy
157// modulo arithmetic. This means that the -1/2 needed by bilerp is actually 1/2 * 1/width for x
158// and 1/2 * 1/height for y. This is what happens when the poorly named fFilterOne{X|Y} is
159// divided by two.
161public:
163 SkPoint* scalarPoint = nullptr) {
164 SkPoint pt;
165 s.fInvProc(s.fInvMatrix,
168
169 SkFixed biasX = 0, biasY = 0;
170 if (s.fBilerp) {
171 biasX = s.fFilterOneX >> 1;
172 biasY = s.fFilterOneY >> 1;
173 } else {
174 // Our rasterizer biases upward. That is a rect from 0.5...1.5 fills pixel 1 and not
175 // pixel 0. To make an image that is mapped 1:1 with device pixels but at a half pixel
176 // offset select every pixel from the src image once we make exact integer pixel sample
177 // values round down not up. Note that a mirror mapping will not have this property.
178 biasX = 1;
179 biasY = 1;
180 }
181
182 // punt to unsigned for defined underflow behavior
183 fX = (SkFractionalInt)((uint64_t)SkScalarToFractionalInt(pt.x()) -
184 (uint64_t)SkFixedToFractionalInt(biasX));
185 fY = (SkFractionalInt)((uint64_t)SkScalarToFractionalInt(pt.y()) -
186 (uint64_t)SkFixedToFractionalInt(biasY));
187
188 if (scalarPoint) {
189 scalarPoint->set(pt.x() - SkFixedToScalar(biasX),
190 pt.y() - SkFixedToScalar(biasY));
191 }
192 }
193
194 SkFractionalInt fractionalIntX() const { return fX; }
195 SkFractionalInt fractionalIntY() const { return fY; }
196
197 SkFixed fixedX() const { return SkFractionalIntToFixed(fX); }
198 SkFixed fixedY() const { return SkFractionalIntToFixed(fY); }
199
200 int intX() const { return SkFractionalIntToInt(fX); }
201 int intY() const { return SkFractionalIntToInt(fY); }
202
203private:
204 SkFractionalInt fX, fY;
205};
206
207namespace sktests {
208 // f is the value to pack, max is the largest the value can be.
209 uint32_t pack_clamp(SkFixed f, unsigned max);
210 // As above, but width is the width of the pretend bitmap.
211 uint32_t pack_repeat(SkFixed f, unsigned max, size_t width);
212 uint32_t pack_mirror(SkFixed f, unsigned max, size_t width);
213}
214
215namespace SkOpts {
216 // SkBitmapProcState optimized Shader, Sample, or Matrix procs.
217 extern void (*S32_alpha_D32_filter_DX)(const SkBitmapProcState&,
218 const uint32_t* xy, int count, SkPMColor*);
219 extern void (*S32_alpha_D32_filter_DXDY)(const SkBitmapProcState&,
220 const uint32_t* xy, int count, SkPMColor*);
221
222 void Init_BitmapProcState();
223} // namespace SkOpts
224
225#endif
static SkM44 inv(const SkM44 &m)
Definition 3d.cpp:26
int count
SkColor4f color
#define SkASSERT(cond)
Definition SkAssert.h:116
#define SkScalarToFractionalInt(x)
#define pack_two_shorts(pri, sec)
#define PACK_TWO_SHORTS(pri, sec)
SkFixed3232 SkFractionalInt
#define SkFractionalIntToFixed(x)
#define SkFractionalIntToInt(x)
#define SkFixedToFractionalInt(x)
unsigned U16CPU
Definition SkCPUTypes.h:23
uint32_t SkColor
Definition SkColor.h:37
uint8_t SkAlpha
Definition SkColor.h:26
uint32_t SkPMColor
Definition SkColor.h:205
int32_t SkFixed
Definition SkFixed.h:25
int64_t SkFixed3232
Definition SkFixed.h:129
#define SkFixedToScalar(x)
Definition SkFixed.h:124
#define SK_ScalarHalf
Definition SkScalar.h:19
#define SkIntToScalar(x)
Definition SkScalar.h:57
SkTileMode
Definition SkTileMode.h:13
SkFractionalInt fractionalIntY() const
SkFractionalInt fractionalIntX() const
SkBitmapProcStateAutoMapper(const SkBitmapProcState &s, int x, int y, SkPoint *scalarPoint=nullptr)
SkMatrix::MapXYProc MapXYProc
sk_sp< SkImage > image
Definition examples.cpp:29
struct MyStruct s
static float max(float r, float g, float b)
Definition hsl.cpp:49
double y
double x
SkTileMode tmy
SkTileMode tmx
int32_t width
void(* ShaderProc32)(const void *ctx, int x, int y, SkPMColor[], int count)
bool setup(const SkMatrix &inv, SkColor color, const SkSamplingOptions &sampling)
ShaderProc32 getShaderProc32() const
SkFractionalInt fInvSxFractionalInt
void(* MatrixProc)(const SkBitmapProcState &, uint32_t bitmapXY[], int count, int x, int y)
SkMatrixPriv::MapXYProc fInvProc
void(* SampleProc32)(const SkBitmapProcState &, const uint32_t[], int count, SkPMColor colors[])
int maxCountForBufferSize(size_t bufferSize) const
const SkImage_Base * fImage
MatrixProc getMatrixProc() const
SampleProc32 getSampleProc32() const
SkFractionalInt fInvKyFractionalInt
constexpr float y() const
constexpr float x() const