| OLD | NEW |
| 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" |
| 11 #include "SkPaint.h" | 11 #include "SkPaint.h" |
| 12 #include "SkShader.h" // for tilemodes | 12 #include "SkShader.h" // for tilemodes |
| 13 #include "SkUtilsArm.h" | 13 #include "SkUtilsArm.h" |
| 14 #include "SkBitmapScaler.h" |
| 14 | 15 |
| 15 #if !SK_ARM_NEON_IS_NONE | 16 #if !SK_ARM_NEON_IS_NONE |
| 16 // These are defined in src/opts/SkBitmapProcState_arm_neon.cpp | 17 // These are defined in src/opts/SkBitmapProcState_arm_neon.cpp |
| 17 extern const SkBitmapProcState::SampleProc16 gSkBitmapProcStateSample16_neon[]; | 18 extern const SkBitmapProcState::SampleProc16 gSkBitmapProcStateSample16_neon[]; |
| 18 extern const SkBitmapProcState::SampleProc32 gSkBitmapProcStateSample32_neon[]; | 19 extern const SkBitmapProcState::SampleProc32 gSkBitmapProcStateSample32_neon[]; |
| 19 extern void S16_D16_filter_DX_neon(const SkBitmapProcState&, const uint32_t*, i
nt, uint16_t*); | 20 extern void S16_D16_filter_DX_neon(const SkBitmapProcState&, const uint32_t*, i
nt, uint16_t*); |
| 20 extern void Clamp_S16_D16_filter_DX_shaderproc_neon(const SkBitmapProcState&, i
nt, int, uint16_t*, int); | 21 extern void Clamp_S16_D16_filter_DX_shaderproc_neon(const SkBitmapProcState&, i
nt, int, uint16_t*, int); |
| 21 extern void Repeat_S16_D16_filter_DX_shaderproc_neon(const SkBitmapProcState&,
int, int, uint16_t*, int); | 22 extern void Repeat_S16_D16_filter_DX_shaderproc_neon(const SkBitmapProcState&,
int, int, uint16_t*, int); |
| 22 extern void SI8_opaque_D32_filter_DX_neon(const SkBitmapProcState&, const uint3
2_t*, int, SkPMColor*); | 23 extern void SI8_opaque_D32_filter_DX_neon(const SkBitmapProcState&, const uint3
2_t*, int, SkPMColor*); |
| 23 extern void SI8_opaque_D32_filter_DX_shaderproc_neon(const SkBitmapProcState&,
int, int, uint32_t*, int); | 24 extern void SI8_opaque_D32_filter_DX_shaderproc_neon(const SkBitmapProcState&,
int, int, uint32_t*, int); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 | 93 |
| 93 // TODO -- we may want to pass the clip into this function so we only scale | 94 // TODO -- we may want to pass the clip into this function so we only scale |
| 94 // the portion of the image that we're going to need. This will complicate | 95 // the portion of the image that we're going to need. This will complicate |
| 95 // the interface to the cache, but might be well worth it. | 96 // the interface to the cache, but might be well worth it. |
| 96 | 97 |
| 97 void SkBitmapProcState::possiblyScaleImage() { | 98 void SkBitmapProcState::possiblyScaleImage() { |
| 98 | 99 |
| 99 if (fFilterQuality != kHQ_BitmapFilter) { | 100 if (fFilterQuality != kHQ_BitmapFilter) { |
| 100 return; | 101 return; |
| 101 } | 102 } |
| 103 |
| 104 // see if our platform has any specialized convolution code. |
| 105 |
| 106 |
| 107 // Set up a pointer to a local (instead of storing the structure in the |
| 108 // proc state) to avoid introducing a header dependency; this makes |
| 109 // recompiles a lot less painful. |
| 110 |
| 111 SkConvolutionProcs simd; |
| 112 fConvolutionProcs = &simd; |
| 113 |
| 114 fConvolutionProcs->fExtraHorizontalReads = 0; |
| 115 fConvolutionProcs->fConvolveVertically = NULL; |
| 116 fConvolutionProcs->fConvolve4RowsHorizontally = NULL; |
| 117 fConvolutionProcs->fConvolveHorizontally = NULL; |
| 118 fConvolutionProcs->fApplySIMDPadding = NULL; |
| 119 |
| 120 this->platformConvolutionProcs(); |
| 102 | 121 |
| 103 // STEP 1: UPSAMPLE? | 122 // STEP 1: Highest quality direct scale? |
| 104 | 123 |
| 105 // Check to see if the transformation matrix is scaling up, and if | 124 // Check to see if the transformation matrix is simple, and if we're |
| 106 // the matrix is simple, and if we're doing high quality scaling. | 125 // doing high quality scaling. If so, do the bitmap scale here and |
| 107 // If so, do the bitmap scale here and remove the scaling component from the
matrix. | 126 // remove the scaling component from the matrix. |
| 108 | 127 |
| 109 if (fInvMatrix.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Ma
sk) && | 128 if (fFilterQuality == kHQ_BitmapFilter && |
| 110 (fInvMatrix.getScaleX() < 1 || fInvMatrix.getScaleY() < 1) && | 129 fInvMatrix.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Ma
sk) && |
| 111 fOrigBitmap.config() == SkBitmap::kARGB_8888_Config) { | 130 fOrigBitmap.config() == SkBitmap::kARGB_8888_Config) { |
| 131 |
| 132 int dest_width = SkScalarCeilToInt(fOrigBitmap.width() / fInvMatrix.get
ScaleX()); |
| 133 int dest_height = SkScalarCeilToInt(fOrigBitmap.height() / fInvMatrix.ge
tScaleY()); |
| 134 |
| 135 // All the criteria are met; let's make a new bitmap. |
| 112 | 136 |
| 113 // All the criteria are met; let's make a new bitmap. | 137 fScaledBitmap = SkBitmapScaler::Resize( fOrigBitmap, SkBitmapScaler::RES
IZE_BEST, |
| 114 fScaledBitmap.setConfig(SkBitmap::kARGB_8888_Config, | 138 dest_width, dest_height, fConvol
utionProcs ); |
| 115 (int)(fOrigBitmap.width() / fInvMatrix.getScaleX
()), | 139 |
| 116 (int)(fOrigBitmap.height() / fInvMatrix.getScale
Y())); | 140 fScaledBitmap.lockPixels(); |
| 117 fScaledBitmap.allocPixels(); | 141 |
| 118 fOrigBitmap.scale(&fScaledBitmap); | |
| 119 fBitmap = &fScaledBitmap; | 142 fBitmap = &fScaledBitmap; |
| 120 | 143 |
| 121 // set the inv matrix type to translate-only; | 144 // set the inv matrix type to translate-only; |
| 122 | 145 |
| 123 fInvMatrix.setTranslate( 1/fInvMatrix.getScaleX() * fInvMatrix.getTransl
ateX(), | 146 fInvMatrix.setTranslate( 1/fInvMatrix.getScaleX() * fInvMatrix.getTransl
ateX(), |
| 124 1/fInvMatrix.getScaleY() * fInvMatrix.getTransl
ateY() ); | 147 1/fInvMatrix.getScaleY() * fInvMatrix.getTransl
ateY() ); |
| 125 | 148 |
| 126 // no need for any further filtering; we just did it! | 149 // no need for any further filtering; we just did it! |
| 127 | 150 |
| 128 fFilterQuality = kNone_BitmapFilter; | 151 fFilterQuality = kNone_BitmapFilter; |
| 129 | 152 |
| 130 return; | 153 return; |
| 131 } | 154 } |
| 132 | 155 |
| 133 if (!fOrigBitmap.hasMipMap()) { | 156 if (!fOrigBitmap.hasMipMap() && fFilterQuality != kNone_BitmapFilter) { |
| 134 | 157 |
| 135 // STEP 2: DOWNSAMPLE | 158 // STEP 2: MIPMAP DOWNSAMPLE? |
| 136 | 159 |
| 137 // Check to see if the transformation matrix is scaling *down*. | 160 // Check to see if the transformation matrix is scaling *down*. |
| 138 // If so, automatically build mipmaps. | 161 // If so, automatically build mipmaps. |
| 139 | 162 |
| 140 SkPoint v1, v2; | 163 SkPoint v1, v2; |
| 141 | 164 |
| 142 // conservatively estimate if the matrix is scaling down by seeing | 165 // conservatively estimate if the matrix is scaling down by seeing |
| 143 // what its upper left 2x2 portion does to two unit vectors. | 166 // what its upper left 2x2 portion does to two unit vectors. |
| 144 | 167 |
| 145 v1.fX = fInvMatrix.getScaleX(); | 168 v1.fX = fInvMatrix.getScaleX(); |
| (...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 848 } else { | 871 } else { |
| 849 size >>= 2; | 872 size >>= 2; |
| 850 } | 873 } |
| 851 | 874 |
| 852 if (fFilterQuality != kNone_BitmapFilter) { | 875 if (fFilterQuality != kNone_BitmapFilter) { |
| 853 size >>= 1; | 876 size >>= 1; |
| 854 } | 877 } |
| 855 | 878 |
| 856 return size; | 879 return size; |
| 857 } | 880 } |
| OLD | NEW |