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

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

Issue 19335002: Production quality fast image up/downsampler (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: clean up use of filter quality flags Created 7 years, 5 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
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"
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
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
119 this->platformConvolutionProcs();
102 120
103 // STEP 1: UPSAMPLE? 121 // STEP 1: Highest quality direct scale?
104 122
105 // Check to see if the transformation matrix is scaling up, and if 123 // 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. 124 // 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. 125 // remove the scaling component from the matrix.
108 126
109 if (fInvMatrix.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Ma sk) && 127 if (fFilterQuality == kHQ_BitmapFilter &&
110 (fInvMatrix.getScaleX() < 1 || fInvMatrix.getScaleY() < 1) && 128 fInvMatrix.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Ma sk) &&
111 fOrigBitmap.config() == SkBitmap::kARGB_8888_Config) { 129 fOrigBitmap.config() == SkBitmap::kARGB_8888_Config) {
130
131 int dest_width = (int)(fOrigBitmap.width() / fInvMatrix.getScaleX()) ;
reed1 2013/07/18 13:42:12 round/ceil/floor?
humper 2013/07/18 17:11:04 Done.
132 int dest_height = (int)(fOrigBitmap.height() / fInvMatrix.getScaleY( ));
133
134 // All the criteria are met; let's make a new bitmap.
112 135
113 // All the criteria are met; let's make a new bitmap. 136 fScaledBitmap = SkBitmapScaler::Resize( fOrigBitmap, SkBitmapScaler::RES IZE_BEST,
114 fScaledBitmap.setConfig(SkBitmap::kARGB_8888_Config, 137 dest_width, dest_height, fConvolutionProcs );
115 (int)(fOrigBitmap.width() / fInvMatrix.getScaleX ()), 138
116 (int)(fOrigBitmap.height() / fInvMatrix.getScale Y())); 139 fScaledBitmap.lockPixels();
117 fScaledBitmap.allocPixels(); 140
118 fOrigBitmap.scale(&fScaledBitmap);
119 fBitmap = &fScaledBitmap; 141 fBitmap = &fScaledBitmap;
120 142
121 // set the inv matrix type to translate-only; 143 // set the inv matrix type to translate-only;
122 144
123 fInvMatrix.setTranslate( 1/fInvMatrix.getScaleX() * fInvMatrix.getTransl ateX(), 145 fInvMatrix.setTranslate( 1/fInvMatrix.getScaleX() * fInvMatrix.getTransl ateX(),
124 1/fInvMatrix.getScaleY() * fInvMatrix.getTransl ateY() ); 146 1/fInvMatrix.getScaleY() * fInvMatrix.getTransl ateY() );
125 147
126 // no need for any further filtering; we just did it! 148 // no need for any further filtering; we just did it!
127 149
128 fFilterQuality = kNone_BitmapFilter; 150 fFilterQuality = kNone_BitmapFilter;
129 151
130 return; 152 return;
131 } 153 }
132 154
133 if (!fOrigBitmap.hasMipMap()) { 155 if (!fOrigBitmap.hasMipMap() && fFilterQuality != kNone_BitmapFilter) {
134 156
135 // STEP 2: DOWNSAMPLE 157 // STEP 2: MIPMAP DOWNSAMPLE?
136 158
137 // Check to see if the transformation matrix is scaling *down*. 159 // Check to see if the transformation matrix is scaling *down*.
138 // If so, automatically build mipmaps. 160 // If so, automatically build mipmaps.
139 161
140 SkPoint v1, v2; 162 SkPoint v1, v2;
141 163
142 // conservatively estimate if the matrix is scaling down by seeing 164 // conservatively estimate if the matrix is scaling down by seeing
143 // what its upper left 2x2 portion does to two unit vectors. 165 // what its upper left 2x2 portion does to two unit vectors.
144 166
145 v1.fX = fInvMatrix.getScaleX(); 167 v1.fX = fInvMatrix.getScaleX();
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 } else { 870 } else {
849 size >>= 2; 871 size >>= 2;
850 } 872 }
851 873
852 if (fFilterQuality != kNone_BitmapFilter) { 874 if (fFilterQuality != kNone_BitmapFilter) {
853 size >>= 1; 875 size >>= 1;
854 } 876 }
855 877
856 return size; 878 return size;
857 } 879 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698