Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Side by Side Diff: src/core/SkBitmapProcState.cpp

Issue 14018020: use forward matrix to determine if we can ignore scale part of a matrix (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « gyp/gmslides.gypi ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 #include "SkBitmapProcState.h" 8 #include "SkBitmapProcState.h"
9 #include "SkColorPriv.h" 9 #include "SkColorPriv.h"
10 #include "SkFilterProc.h" 10 #include "SkFilterProc.h"
(...skipping 12 matching lines...) Expand all
23 extern void SI8_opaque_D32_filter_DX_shaderproc_neon(const SkBitmapProcState&, int, int, uint32_t*, int); 23 extern void SI8_opaque_D32_filter_DX_shaderproc_neon(const SkBitmapProcState&, int, int, uint32_t*, int);
24 extern void Clamp_SI8_opaque_D32_filter_DX_shaderproc_neon(const SkBitmapProcSt ate&, int, int, uint32_t*, int); 24 extern void Clamp_SI8_opaque_D32_filter_DX_shaderproc_neon(const SkBitmapProcSt ate&, int, int, uint32_t*, int);
25 #endif 25 #endif
26 26
27 #define NAME_WRAP(x) x 27 #define NAME_WRAP(x) x
28 #include "SkBitmapProcState_filter.h" 28 #include "SkBitmapProcState_filter.h"
29 #include "SkBitmapProcState_procs.h" 29 #include "SkBitmapProcState_procs.h"
30 30
31 /////////////////////////////////////////////////////////////////////////////// 31 ///////////////////////////////////////////////////////////////////////////////
32 32
33 // true iff the matrix contains, at most, scale and translate elements
34 static bool matrix_only_scale_translate(const SkMatrix& m) {
35 return m.getType() <= SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask;
36 }
37
33 /** 38 /**
34 * For the purposes of drawing bitmaps, if a matrix is "almost" translate 39 * For the purposes of drawing bitmaps, if a matrix is "almost" translate
35 * go ahead and treat it as if it were, so that subsequent code can go fast. 40 * go ahead and treat it as if it were, so that subsequent code can go fast.
36 */ 41 */
37 static bool just_trans_clamp(const SkMatrix& matrix, const SkBitmap& bitmap) { 42 static bool just_trans_clamp(const SkMatrix& matrix, const SkBitmap& bitmap) {
38 SkMatrix::TypeMask mask = matrix.getType(); 43 SkASSERT(matrix_only_scale_translate(matrix));
39 44
40 if (mask & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)) { 45 if (matrix.getType() & SkMatrix::kScale_Mask) {
41 return false; 46 SkRect src, dst;
42 } 47 bitmap.getBounds(&src);
43 if (mask & SkMatrix::kScale_Mask) { 48 matrix.mapRect(&dst, src);
44 SkScalar sx = matrix[SkMatrix::kMScaleX]; 49
45 SkScalar sy = matrix[SkMatrix::kMScaleY]; 50 // Now round all 4 edges to device space, and then compare the device
46 int w = bitmap.width(); 51 // width/height to the original. Note: we must map all 4 and subtract
47 int h = bitmap.height(); 52 // rather than map the "width" and compare, since we care about the
48 int sw = SkScalarRound(SkScalarMul(sx, SkIntToScalar(w))); 53 // phase (in pixel space) that any translate in the matrix might impart.
49 int sh = SkScalarRound(SkScalarMul(sy, SkIntToScalar(h))); 54 SkIRect idst;
50 return sw == w && sh == h; 55 dst.round(&idst);
56 return idst.width() == bitmap.width() && idst.height() == bitmap.height( );
51 } 57 }
52 // if we got here, we're either kTranslate_Mask or identity 58 // if we got here, we're either kTranslate_Mask or identity
53 return true; 59 return true;
54 } 60 }
55 61
56 static bool just_trans_general(const SkMatrix& matrix) { 62 static bool just_trans_general(const SkMatrix& matrix) {
57 SkMatrix::TypeMask mask = matrix.getType(); 63 SkASSERT(matrix_only_scale_translate(matrix));
58 64
59 if (mask & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)) { 65 if (matrix.getType() & SkMatrix::kScale_Mask) {
60 return false;
61 }
62 if (mask & SkMatrix::kScale_Mask) {
63 const SkScalar tol = SK_Scalar1 / 32768; 66 const SkScalar tol = SK_Scalar1 / 32768;
64 67
65 if (!SkScalarNearlyZero(matrix[SkMatrix::kMScaleX] - SK_Scalar1, tol)) { 68 if (!SkScalarNearlyZero(matrix[SkMatrix::kMScaleX] - SK_Scalar1, tol)) {
66 return false; 69 return false;
67 } 70 }
68 if (!SkScalarNearlyZero(matrix[SkMatrix::kMScaleY] - SK_Scalar1, tol)) { 71 if (!SkScalarNearlyZero(matrix[SkMatrix::kMScaleY] - SK_Scalar1, tol)) {
69 return false; 72 return false;
70 } 73 }
71 } 74 }
72 // if we got here, treat us as either kTranslate_Mask or identity 75 // if we got here, treat us as either kTranslate_Mask or identity
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 116
114 SkScalar scale = SkFixedToScalar(SK_Fixed1 >> shift); 117 SkScalar scale = SkFixedToScalar(SK_Fixed1 >> shift);
115 fUnitInvMatrix.postScale(scale, scale); 118 fUnitInvMatrix.postScale(scale, scale);
116 119
117 // now point here instead of fOrigBitmap 120 // now point here instead of fOrigBitmap
118 fBitmap = &fMipBitmap; 121 fBitmap = &fMipBitmap;
119 } 122 }
120 } 123 }
121 124
122 // wack our matrix to exactly no-scale, if we're really close to begin with 125 // wack our matrix to exactly no-scale, if we're really close to begin with
123 { 126 if (matrix_only_scale_translate(*m)) {
124 bool fixupMatrix = clamp_clamp ? 127 SkMatrix forward;
125 just_trans_clamp(*m, *fBitmap) : just_trans_general(*m); 128 if (m->invert(&forward)) {
126 if (fixupMatrix) { 129 if (clamp_clamp ? just_trans_clamp(forward, *fBitmap)
127 // If we can be treated just like translate, construct that inverse 130 : just_trans_general(forward)) {
128 // such that we landed in the proper place. Given that m may have
129 // some slight scale, we have to invert it to compute this new
130 // matrix.
131 SkMatrix forward;
132 if (m->invert(&forward)) {
133 SkScalar tx = -SkScalarRoundToScalar(forward.getTranslateX()); 131 SkScalar tx = -SkScalarRoundToScalar(forward.getTranslateX());
134 SkScalar ty = -SkScalarRoundToScalar(forward.getTranslateY()); 132 SkScalar ty = -SkScalarRoundToScalar(forward.getTranslateY());
135 fUnitInvMatrix.setTranslate(tx, ty); 133 fUnitInvMatrix.setTranslate(tx, ty);
136 m = &fUnitInvMatrix; 134 m = &fUnitInvMatrix;
137 // now the following code will sniff m, and decide to take the 135 // now the following code will sniff m, and decide to take the
138 // fast case (since m is purely translate). 136 // fast case (since m is purely translate).
139 } 137 }
140 } 138 }
141 } 139 }
142 140
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 } else { 709 } else {
712 size >>= 2; 710 size >>= 2;
713 } 711 }
714 712
715 if (fDoFilter) { 713 if (fDoFilter) {
716 size >>= 1; 714 size >>= 1;
717 } 715 }
718 716
719 return size; 717 return size;
720 } 718 }
OLDNEW
« no previous file with comments | « gyp/gmslides.gypi ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698