Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkBitmapProcState.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2011 Google Inc.
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
9
17#include "src/core/SkMemset.h"
19
20#include <algorithm>
21#include <cstring>
22#include <tuple>
23
24class SkImage;
25class SkImage_Base;
26
27// One-stop-shop shader for,
28// - nearest-neighbor sampling (_nofilter_),
29// - clamp tiling in X and Y both (Clamp_),
30// - with at most a scale and translate matrix (_DX_),
31// - and no extra alpha applied (_opaque_),
32// - sampling from 8888 (_S32_) and drawing to 8888 (_S32_).
33static void Clamp_S32_opaque_D32_nofilter_DX_shaderproc(const void* sIn, int x, int y,
34 SkPMColor* dst, int count) {
35 const SkBitmapProcState& s = *static_cast<const SkBitmapProcState*>(sIn);
36 SkASSERT(s.fInvMatrix.isScaleTranslate());
37 SkASSERT(s.fAlphaScale == 256);
38
39 const unsigned maxX = s.fPixmap.width() - 1;
41 int dstY;
42 {
43 const SkBitmapProcStateAutoMapper mapper(s, x, y);
44 const unsigned maxY = s.fPixmap.height() - 1;
45 dstY = SkTPin<int>(mapper.intY(), 0, maxY);
46 fx = mapper.fractionalIntX();
47 }
48
49 const SkPMColor* src = s.fPixmap.addr32(0, dstY);
50 const SkFractionalInt dx = s.fInvSxFractionalInt;
51
52 // Check if we're safely inside [0...maxX] so no need to clamp each computed index.
53 //
54 if ((uint64_t)SkFractionalIntToInt(fx) <= maxX &&
55 (uint64_t)SkFractionalIntToInt(fx + dx * (count - 1)) <= maxX)
56 {
57 int count4 = count >> 2;
58 for (int i = 0; i < count4; ++i) {
59 SkPMColor src0 = src[SkFractionalIntToInt(fx)]; fx += dx;
60 SkPMColor src1 = src[SkFractionalIntToInt(fx)]; fx += dx;
61 SkPMColor src2 = src[SkFractionalIntToInt(fx)]; fx += dx;
62 SkPMColor src3 = src[SkFractionalIntToInt(fx)]; fx += dx;
63 dst[0] = src0;
64 dst[1] = src1;
65 dst[2] = src2;
66 dst[3] = src3;
67 dst += 4;
68 }
69 for (int i = (count4 << 2); i < count; ++i) {
70 unsigned index = SkFractionalIntToInt(fx);
71 SkASSERT(index <= maxX);
72 *dst++ = src[index];
73 fx += dx;
74 }
75 } else {
76 for (int i = 0; i < count; ++i) {
77 dst[i] = src[SkTPin<int>(SkFractionalIntToInt(fx), 0, maxX)];
78 fx += dx;
79 }
80 }
81}
82
84 const uint32_t* xy, int count, SkPMColor* colors) {
85 SkASSERT(count > 0 && colors != nullptr);
86 SkASSERT(s.fInvMatrix.isScaleTranslate());
87 SkASSERT(!s.fBilerp);
88 SkASSERT(4 == s.fPixmap.info().bytesPerPixel());
89 SkASSERT(s.fAlphaScale <= 256);
90
91 // xy is a 32-bit y-coordinate, followed by 16-bit x-coordinates.
92 unsigned y = *xy++;
93 SkASSERT(y < (unsigned)s.fPixmap.height());
94
95 auto row = (const SkPMColor*)( (const char*)s.fPixmap.addr() + y * s.fPixmap.rowBytes() );
96
97 if (1 == s.fPixmap.width()) {
98 SkOpts::memset32(colors, SkAlphaMulQ(row[0], s.fAlphaScale), count);
99 return;
100 }
101
102 // Step 4 xs == 2 uint32_t at a time.
103 while (count >= 4) {
104 uint32_t x01 = *xy++,
105 x23 = *xy++;
106
107 SkPMColor p0 = row[UNPACK_PRIMARY_SHORT (x01)];
108 SkPMColor p1 = row[UNPACK_SECONDARY_SHORT(x01)];
109 SkPMColor p2 = row[UNPACK_PRIMARY_SHORT (x23)];
110 SkPMColor p3 = row[UNPACK_SECONDARY_SHORT(x23)];
111
112 *colors++ = SkAlphaMulQ(p0, s.fAlphaScale);
113 *colors++ = SkAlphaMulQ(p1, s.fAlphaScale);
114 *colors++ = SkAlphaMulQ(p2, s.fAlphaScale);
115 *colors++ = SkAlphaMulQ(p3, s.fAlphaScale);
116
117 count -= 4;
118 }
119
120 // Step 1 x == 1 uint16_t at a time.
121 auto x = (const uint16_t*)xy;
122 while (count --> 0) {
123 *colors++ = SkAlphaMulQ(row[*x++], s.fAlphaScale);
124 }
125}
126
128 const uint32_t* xy, int count, SkPMColor* colors) {
129 SkASSERT(count > 0 && colors != nullptr);
130 SkASSERT(!s.fBilerp);
131 SkASSERT(4 == s.fPixmap.info().bytesPerPixel());
132 SkASSERT(s.fAlphaScale <= 256);
133
134 auto src = (const char*)s.fPixmap.addr();
135 size_t rb = s.fPixmap.rowBytes();
136
137 while (count --> 0) {
138 uint32_t XY = *xy++,
139 x = XY & 0xffff,
140 y = XY >> 16;
141 SkASSERT(x < (unsigned)s.fPixmap.width ());
142 SkASSERT(y < (unsigned)s.fPixmap.height());
143 *colors++ = SkAlphaMulQ(((const SkPMColor*)(src + y*rb))[x], s.fAlphaScale);
144 }
145}
146
148 : fImage(image)
149 , fTileModeX(tmx)
150 , fTileModeY(tmy)
151{}
152
153// true iff the matrix has a scale and no more than an optional translate.
155 return (m.getType() & ~SkMatrix::kTranslate_Mask) == SkMatrix::kScale_Mask;
156}
157
158/**
159 * For the purposes of drawing bitmaps, if a matrix is "almost" translate
160 * go ahead and treat it as if it were, so that subsequent code can go fast.
161 */
162static bool just_trans_general(const SkMatrix& matrix) {
164
165 const SkScalar tol = SK_Scalar1 / 32768;
166
169}
170
171/**
172 * Determine if the matrix can be treated as integral-only-translate,
173 * for the purpose of filtering.
174 */
175static bool just_trans_integral(const SkMatrix& m) {
176 static constexpr SkScalar tol = SK_Scalar1 / 256;
177
178 return m.getType() <= SkMatrix::kTranslate_Mask
179 && SkScalarNearlyEqual(m.getTranslateX(), SkScalarRoundToScalar(m.getTranslateX()), tol)
180 && SkScalarNearlyEqual(m.getTranslateY(), SkScalarRoundToScalar(m.getTranslateY()), tol);
181}
182
183static bool valid_for_filtering(unsigned dimension) {
184 // for filtering, width and height must fit in 14bits, since we use steal
185 // 2 bits from each to store our 4bit subpixel data
186 return (dimension & ~0x3FFF) == 0;
187}
188
189bool SkBitmapProcState::init(const SkMatrix& inv, SkAlpha paintAlpha,
190 const SkSamplingOptions& sampling) {
191 SkASSERT(!inv.hasPerspective());
192 SkASSERT(SkOpts::S32_alpha_D32_filter_DXDY || inv.isScaleTranslate());
196
197 fPixmap.reset();
198 fBilerp = false;
199
200 auto* access = SkMipmapAccessor::Make(&fAlloc, (const SkImage*)fImage, inv, sampling.mipmap);
201 if (!access) {
202 return false;
203 }
204 std::tie(fPixmap, fInvMatrix) = access->level();
206
207 fPaintAlpha = paintAlpha;
210
211 bool integral_translate_only = just_trans_integral(fInvMatrix);
212 if (!integral_translate_only) {
213 // Most of the scanline procs deal with "unit" texture coordinates, as this
214 // makes it easy to perform tiling modes (repeat = (x & 0xFFFF)). To generate
215 // those, we divide the matrix by its dimensions here.
216 //
217 // We don't do this if we're either trivial (can ignore the matrix) or clamping
218 // in both X and Y since clamping to width,height is just as easy as to 0xFFFF.
219
222 }
223
224 // Now that all possible changes to the matrix have taken place, check
225 // to see if we're really close to a no-scale matrix. If so, explicitly
226 // set it to be so. Subsequent code may inspect this matrix to choose
227 // a faster path in this case.
228
229 // This code will only execute if the matrix has some scale component;
230 // if it's already pure translate then we won't do this inversion.
231
233 SkMatrix forward;
234 if (fInvMatrix.invert(&forward) && just_trans_general(forward)) {
235 fInvMatrix.setTranslate(-forward.getTranslateX(), -forward.getTranslateY());
236 }
237 }
238
239 // Recompute the flag after matrix adjustments.
240 integral_translate_only = just_trans_integral(fInvMatrix);
241 }
242
243 if (fBilerp &&
244 (!valid_for_filtering(fPixmap.width() | fPixmap.height()) || integral_translate_only)) {
245 fBilerp = false;
246 }
247
248 return true;
249}
250
251/*
252 * Analyze filter-quality and matrix, and decide how to implement that.
253 *
254 * In general, we cascade down the request level [ High ... None ]
255 * - for a given level, if we can fulfill it, fine, else
256 * - else we downgrade to the next lower level and try again.
257 * We can always fulfill requests for Low and None
258 * - sometimes we will "ignore" Low and give None, but this is likely a legacy perf hack
259 * and may be removed.
260 */
261bool SkBitmapProcState::chooseProcs() {
263 SkASSERT(SkOpts::S32_alpha_D32_filter_DXDY || fInvMatrix.isScaleTranslate());
264 SkASSERT(fPixmap.colorType() == kN32_SkColorType);
267
269
273
275
276 bool translate_only = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) == 0;
277 fMatrixProc = this->chooseMatrixProc(translate_only);
278 SkASSERT(fMatrixProc);
279
281 fSampleProc32 = fBilerp ? SkOpts::S32_alpha_D32_filter_DX : S32_alpha_D32_nofilter_DX ;
282 } else {
283 fSampleProc32 = fBilerp ? SkOpts::S32_alpha_D32_filter_DXDY : S32_alpha_D32_nofilter_DXDY;
284 }
285 SkASSERT(fSampleProc32);
286
287 // our special-case shaderprocs
288 // TODO: move this one into chooseShaderProc32() or pull all that in here.
289 if (fAlphaScale == 256
290 && !fBilerp
295 } else {
296 fShaderProc32 = this->chooseShaderProc32();
297 }
298
299 return true;
300}
301
302static void Clamp_S32_D32_nofilter_trans_shaderproc(const void* sIn,
303 int x, int y,
304 SkPMColor* colors,
305 int count) {
306 const SkBitmapProcState& s = *static_cast<const SkBitmapProcState*>(sIn);
307 SkASSERT(s.fInvMatrix.isTranslate());
308 SkASSERT(count > 0 && colors != nullptr);
309 SkASSERT(!s.fBilerp);
310
311 const int maxX = s.fPixmap.width() - 1;
312 const int maxY = s.fPixmap.height() - 1;
313 int ix = s.fFilterOneX + x;
314 int iy = SkTPin(s.fFilterOneY + y, 0, maxY);
315 const SkPMColor* row = s.fPixmap.addr32(0, iy);
316
317 // clamp to the left
318 if (ix < 0) {
319 int n = std::min(-ix, count);
320 SkOpts::memset32(colors, row[0], n);
321 count -= n;
322 if (0 == count) {
323 return;
324 }
325 colors += n;
326 SkASSERT(-ix == n);
327 ix = 0;
328 }
329 // copy the middle
330 if (ix <= maxX) {
331 int n = std::min(maxX - ix + 1, count);
332 memcpy(colors, row + ix, n * sizeof(SkPMColor));
333 count -= n;
334 if (0 == count) {
335 return;
336 }
337 colors += n;
338 }
339 SkASSERT(count > 0);
340 // clamp to the right
341 SkOpts::memset32(colors, row[maxX], count);
342}
343
344static inline int sk_int_mod(int x, int n) {
345 SkASSERT(n > 0);
346 if ((unsigned)x >= (unsigned)n) {
347 if (x < 0) {
348 x = n + ~(~x % n);
349 } else {
350 x = x % n;
351 }
352 }
353 return x;
354}
355
356static inline int sk_int_mirror(int x, int n) {
357 x = sk_int_mod(x, 2 * n);
358 if (x >= n) {
359 x = n + ~(x - n);
360 }
361 return x;
362}
363
365 int x, int y,
366 SkPMColor* colors,
367 int count) {
368 const SkBitmapProcState& s = *static_cast<const SkBitmapProcState*>(sIn);
369 SkASSERT(s.fInvMatrix.isTranslate());
370 SkASSERT(count > 0 && colors != nullptr);
371 SkASSERT(!s.fBilerp);
372
373 const int stopX = s.fPixmap.width();
374 const int stopY = s.fPixmap.height();
375 int ix = s.fFilterOneX + x;
376 int iy = sk_int_mod(s.fFilterOneY + y, stopY);
377 const SkPMColor* row = s.fPixmap.addr32(0, iy);
378
379 ix = sk_int_mod(ix, stopX);
380 for (;;) {
381 int n = std::min(stopX - ix, count);
382 memcpy(colors, row + ix, n * sizeof(SkPMColor));
383 count -= n;
384 if (0 == count) {
385 return;
386 }
387 colors += n;
388 ix = 0;
389 }
390}
391
392static inline void filter_32_alpha(unsigned t,
393 SkPMColor color0,
394 SkPMColor color1,
395 SkPMColor* dstColor,
396 unsigned alphaScale) {
397 SkASSERT((unsigned)t <= 0xF);
398 SkASSERT(alphaScale <= 256);
399
400 const uint32_t mask = 0xFF00FF;
401
402 int scale = 256 - 16*t;
403 uint32_t lo = (color0 & mask) * scale;
404 uint32_t hi = ((color0 >> 8) & mask) * scale;
405
406 scale = 16*t;
407 lo += (color1 & mask) * scale;
408 hi += ((color1 >> 8) & mask) * scale;
409
410 // TODO: if (alphaScale < 256) ...
411 lo = ((lo >> 8) & mask) * alphaScale;
412 hi = ((hi >> 8) & mask) * alphaScale;
413
414 *dstColor = ((lo >> 8) & mask) | (hi & ~mask);
415}
416
417static void S32_D32_constX_shaderproc(const void* sIn,
418 int x, int y,
419 SkPMColor* colors,
420 int count) {
421 const SkBitmapProcState& s = *static_cast<const SkBitmapProcState*>(sIn);
422 SkASSERT(s.fInvMatrix.isScaleTranslate());
423 SkASSERT(count > 0 && colors != nullptr);
424 SkASSERT(1 == s.fPixmap.width());
425
426 int iY0;
428 int iSubY SK_INIT_TO_AVOID_WARNING;
429
430 if (s.fBilerp) {
431 SkBitmapProcState::MatrixProc mproc = s.getMatrixProc();
432 uint32_t xy[2];
433
434 mproc(s, xy, 1, x, y);
435
436 iY0 = xy[0] >> 18;
437 iY1 = xy[0] & 0x3FFF;
438 iSubY = (xy[0] >> 14) & 0xF;
439 } else {
440 int yTemp;
441
442 if (s.fInvMatrix.isTranslate()) {
443 yTemp = s.fFilterOneY + y;
444 } else{
445 const SkBitmapProcStateAutoMapper mapper(s, x, y);
446
447 // When the matrix has a scale component the setup code in
448 // chooseProcs multiples the inverse matrix by the inverse of the
449 // bitmap's width and height. Since this method is going to do
450 // its own tiling and sampling we need to undo that here.
451 if (SkTileMode::kClamp != s.fTileModeX || SkTileMode::kClamp != s.fTileModeY) {
452 yTemp = SkFractionalIntToInt(mapper.fractionalIntY() * s.fPixmap.height());
453 } else {
454 yTemp = mapper.intY();
455 }
456 }
457
458 const int stopY = s.fPixmap.height();
459 switch (s.fTileModeY) {
461 iY0 = SkTPin(yTemp, 0, stopY-1);
462 break;
464 iY0 = sk_int_mod(yTemp, stopY);
465 break;
467 default:
468 iY0 = sk_int_mirror(yTemp, stopY);
469 break;
470 }
471
472#ifdef SK_DEBUG
473 {
474 const SkBitmapProcStateAutoMapper mapper(s, x, y);
475 int iY2;
476
477 if (!s.fInvMatrix.isTranslate() &&
478 (SkTileMode::kClamp != s.fTileModeX || SkTileMode::kClamp != s.fTileModeY)) {
479 iY2 = SkFractionalIntToInt(mapper.fractionalIntY() * s.fPixmap.height());
480 } else {
481 iY2 = mapper.intY();
482 }
483
484 switch (s.fTileModeY) {
486 iY2 = SkTPin(iY2, 0, stopY-1);
487 break;
489 iY2 = sk_int_mod(iY2, stopY);
490 break;
492 default:
493 iY2 = sk_int_mirror(iY2, stopY);
494 break;
495 }
496
497 SkASSERT(iY0 == iY2);
498 }
499#endif
500 }
501
502 const SkPMColor* row0 = s.fPixmap.addr32(0, iY0);
504
505 if (s.fBilerp) {
506 const SkPMColor* row1 = s.fPixmap.addr32(0, iY1);
507 filter_32_alpha(iSubY, *row0, *row1, &color, s.fAlphaScale);
508 } else {
509 if (s.fAlphaScale < 256) {
510 color = SkAlphaMulQ(*row0, s.fAlphaScale);
511 } else {
512 color = *row0;
513 }
514 }
515
516 SkOpts::memset32(colors, color, count);
517}
518
519static void DoNothing_shaderproc(const void*, int x, int y,
520 SkPMColor* colors, int count) {
521 // if we get called, the matrix is too tricky, so we just draw nothing
522 SkOpts::memset32(colors, 0, count);
523}
524
525bool SkBitmapProcState::setupForTranslate() {
526 SkPoint pt;
527 const SkBitmapProcStateAutoMapper mapper(*this, 0, 0, &pt);
528
529 /*
530 * if the translate is larger than our ints, we can get random results, or
531 * worse, we might get 0x80000000, which wreaks havoc on us, since we can't
532 * negate it.
533 */
534 const SkScalar too_big = SkIntToScalar(1 << 30);
535 if (SkScalarAbs(pt.fX) > too_big || SkScalarAbs(pt.fY) > too_big) {
536 return false;
537 }
538
539 // Since we know we're not filtered, we re-purpose these fields allow
540 // us to go from device -> src coordinates w/ just an integer add,
541 // rather than running through the inverse-matrix
542 fFilterOneX = mapper.intX();
543 fFilterOneY = mapper.intY();
544
545 return true;
546}
547
548SkBitmapProcState::ShaderProc32 SkBitmapProcState::chooseShaderProc32() {
549
550 if (kN32_SkColorType != fPixmap.colorType()) {
551 return nullptr;
552 }
553
554 if (1 == fPixmap.width() && fInvMatrix.isScaleTranslate()) {
555 if (!fBilerp && fInvMatrix.isTranslate() && !this->setupForTranslate()) {
557 }
559 }
560
561 if (fAlphaScale < 256) {
562 return nullptr;
563 }
564 if (!fInvMatrix.isTranslate()) {
565 return nullptr;
566 }
567 if (fBilerp) {
568 return nullptr;
569 }
570
573
574 if (SkTileMode::kClamp == tx && SkTileMode::kClamp == ty) {
575 if (this->setupForTranslate()) {
577 }
579 }
580 if (SkTileMode::kRepeat == tx && SkTileMode::kRepeat == ty) {
581 if (this->setupForTranslate()) {
583 }
585 }
586 return nullptr;
587}
588
589#ifdef SK_DEBUG
590
591static void check_scale_nofilter(uint32_t bitmapXY[], int count,
592 unsigned mx, unsigned my) {
593 unsigned y = *bitmapXY++;
594 SkASSERT(y < my);
595
596 const uint16_t* xptr = reinterpret_cast<const uint16_t*>(bitmapXY);
597 for (int i = 0; i < count; ++i) {
598 SkASSERT(xptr[i] < mx);
599 }
600}
601
602static void check_scale_filter(uint32_t bitmapXY[], int count,
603 unsigned mx, unsigned my) {
604 uint32_t YY = *bitmapXY++;
605 unsigned y0 = YY >> 18;
606 unsigned y1 = YY & 0x3FFF;
607 SkASSERT(y0 < my);
608 SkASSERT(y1 < my);
609
610 for (int i = 0; i < count; ++i) {
611 uint32_t XX = bitmapXY[i];
612 unsigned x0 = XX >> 18;
613 unsigned x1 = XX & 0x3FFF;
614 SkASSERT(x0 < mx);
615 SkASSERT(x1 < mx);
616 }
617}
618
619static void check_affine_nofilter(uint32_t bitmapXY[], int count, unsigned mx, unsigned my) {
620 for (int i = 0; i < count; ++i) {
621 uint32_t XY = bitmapXY[i];
622 unsigned x = XY & 0xFFFF;
623 unsigned y = XY >> 16;
624 SkASSERT(x < mx);
625 SkASSERT(y < my);
626 }
627}
628
629static void check_affine_filter(uint32_t bitmapXY[], int count, unsigned mx, unsigned my) {
630 for (int i = 0; i < count; ++i) {
631 uint32_t YY = *bitmapXY++;
632 unsigned y0 = YY >> 18;
633 unsigned y1 = YY & 0x3FFF;
634 SkASSERT(y0 < my);
635 SkASSERT(y1 < my);
636
637 uint32_t XX = *bitmapXY++;
638 unsigned x0 = XX >> 18;
639 unsigned x1 = XX & 0x3FFF;
640 SkASSERT(x0 < mx);
641 SkASSERT(x1 < mx);
642 }
643}
644
645void SkBitmapProcState::DebugMatrixProc(const SkBitmapProcState& state,
646 uint32_t bitmapXY[], int count,
647 int x, int y) {
648 SkASSERT(bitmapXY);
649 SkASSERT(count > 0);
650
651 state.fMatrixProc(state, bitmapXY, count, x, y);
652
653 void (*proc)(uint32_t bitmapXY[], int count, unsigned mx, unsigned my);
654
655 if (state.fInvMatrix.isScaleTranslate()) {
656 proc = state.fBilerp ? check_scale_filter : check_scale_nofilter;
657 } else {
658 proc = state.fBilerp ? check_affine_filter : check_affine_nofilter;
659 }
660
661 proc(bitmapXY, count, state.fPixmap.width(), state.fPixmap.height());
662}
663
665 return DebugMatrixProc;
666}
667
668#endif
669
670/*
671 The storage requirements for the different matrix procs are as follows,
672 where each X or Y is 2 bytes, and N is the number of pixels/elements:
673
674 scale/translate nofilter Y(4bytes) + N * X
675 affine/perspective nofilter N * (X Y)
676 scale/translate filter Y Y + N * (X X)
677 affine filter N * (Y Y X X)
678 */
679int SkBitmapProcState::maxCountForBufferSize(size_t bufferSize) const {
680 int32_t size = static_cast<int32_t>(bufferSize);
681
682 size &= ~3; // only care about 4-byte aligned chunks
684 size -= 4; // the shared Y (or YY) coordinate
685 if (size < 0) {
686 size = 0;
687 }
688 size >>= 1;
689 } else {
690 size >>= 2;
691 }
692
693 if (fBilerp) {
694 size >>= 1;
695 }
696
697 return size;
698}
699
static SkM44 inv(const SkM44 &m)
Definition 3d.cpp:26
int count
SkColor4f color
@ kOpaque_SkAlphaType
pixel is opaque
Definition SkAlphaType.h:28
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition SkAlphaType.h:29
#define SkASSERT(cond)
Definition SkAssert.h:116
static void filter_32_alpha(unsigned t, SkPMColor color0, SkPMColor color1, SkPMColor *dstColor, unsigned alphaScale)
static void Repeat_S32_D32_nofilter_trans_shaderproc(const void *sIn, int x, int y, SkPMColor *colors, int count)
static void DoNothing_shaderproc(const void *, int x, int y, SkPMColor *colors, int count)
static int sk_int_mirror(int x, int n)
static void Clamp_S32_D32_nofilter_trans_shaderproc(const void *sIn, int x, int y, SkPMColor *colors, int count)
static void Clamp_S32_opaque_D32_nofilter_DX_shaderproc(const void *sIn, int x, int y, SkPMColor *dst, int count)
static bool matrix_only_scale_translate(const SkMatrix &m)
static void S32_D32_constX_shaderproc(const void *sIn, int x, int y, SkPMColor *colors, int count)
static bool just_trans_general(const SkMatrix &matrix)
static bool valid_for_filtering(unsigned dimension)
static void S32_alpha_D32_nofilter_DXDY(const SkBitmapProcState &s, const uint32_t *xy, int count, SkPMColor *colors)
static int sk_int_mod(int x, int n)
static bool just_trans_integral(const SkMatrix &m)
static void S32_alpha_D32_nofilter_DX(const SkBitmapProcState &s, const uint32_t *xy, int count, SkPMColor *colors)
#define UNPACK_PRIMARY_SHORT(packed)
#define UNPACK_SECONDARY_SHORT(packed)
#define SkScalarToFractionalInt(x)
SkFixed3232 SkFractionalInt
#define SkFractionalIntToInt(x)
static SK_ALWAYS_INLINE uint32_t SkAlphaMulQ(uint32_t c, unsigned scale)
static unsigned SkAlpha255To256(U8CPU alpha)
Definition SkColorPriv.h:24
uint8_t SkAlpha
Definition SkColor.h:26
uint32_t SkPMColor
Definition SkColor.h:205
#define SK_INIT_TO_AVOID_WARNING
Definition SkMacros.h:58
static bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance=SK_ScalarNearlyZero)
Definition SkScalar.h:101
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition SkScalar.h:107
#define SK_Scalar1
Definition SkScalar.h:18
#define SkIntToScalar(x)
Definition SkScalar.h:57
#define SkScalarRoundToScalar(x)
Definition SkScalar.h:32
#define SkScalarAbs(x)
Definition SkScalar.h:39
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
Definition SkTPin.h:19
SkTileMode
Definition SkTileMode.h:13
#define XX(width, name,...)
SkFractionalInt fractionalIntY() const
SkFractionalInt fractionalIntX() const
static MapXYProc GetMapXYProc(const SkMatrix &matrix)
static bool PostIDiv(SkMatrix *matrix, int divx, int divy)
static constexpr int kMScaleX
horizontal scale factor
Definition SkMatrix.h:353
SkScalar getSkewY() const
Definition SkMatrix.h:430
SkScalar getTranslateY() const
Definition SkMatrix.h:452
SkMatrix & setTranslate(SkScalar dx, SkScalar dy)
Definition SkMatrix.cpp:254
bool invert(SkMatrix *inverse) const
Definition SkMatrix.h:1206
bool isTranslate() const
Definition SkMatrix.h:248
SkScalar getScaleX() const
Definition SkMatrix.h:415
SkMatrix & preConcat(const SkMatrix &other)
Definition SkMatrix.cpp:674
bool isScaleTranslate() const
Definition SkMatrix.h:236
bool hasPerspective() const
Definition SkMatrix.h:312
static constexpr int kMScaleY
vertical scale factor
Definition SkMatrix.h:357
SkScalar getTranslateX() const
Definition SkMatrix.h:445
@ kTranslate_Mask
translation SkMatrix
Definition SkMatrix.h:193
@ kScale_Mask
scale SkMatrix
Definition SkMatrix.h:194
TypeMask getType() const
Definition SkMatrix.h:207
static SkMipmapAccessor * Make(SkArenaAlloc *, const SkImage *, const SkMatrix &inv, SkMipmapMode)
int width() const
Definition SkPixmap.h:160
SkColorType colorType() const
Definition SkPixmap.h:173
const void * addr() const
Definition SkPixmap.h:153
int height() const
Definition SkPixmap.h:166
SkAlphaType alphaType() const
Definition SkPixmap.h:175
void reset()
Definition SkPixmap.cpp:32
sk_sp< SkImage > image
Definition examples.cpp:29
float SkScalar
Definition extension.cpp:12
struct MyStruct s
AtkStateType state
double y
double x
void(* memset32)(uint32_t[], uint32_t, int)
SkSamplingOptions sampling
Definition SkRecords.h:337
SkTileMode tmy
SkTileMode tmx
const Scalar scale
void(* ShaderProc32)(const void *ctx, int x, int y, SkPMColor[], int count)
SkBitmapProcState(const SkImage_Base *image, SkTileMode tmx, SkTileMode tmy)
SkFractionalInt fInvSxFractionalInt
void(* MatrixProc)(const SkBitmapProcState &, uint32_t bitmapXY[], int count, int x, int y)
SkMatrixPriv::MapXYProc fInvProc
int maxCountForBufferSize(size_t bufferSize) const
const SkImage_Base * fImage
MatrixProc getMatrixProc() const
SkFractionalInt fInvKyFractionalInt
float fX
x-axis value
float fY
y-axis value
const SkFilterMode filter
const SkMipmapMode mipmap