Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkBitmapProcShader.h" | 8 #include "SkBitmapProcShader.h" |
| 9 #include "SkBitmapProcState.h" | 9 #include "SkBitmapProcState.h" |
| 10 #include "SkBitmapProvider.h" | 10 #include "SkBitmapProvider.h" |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 60 }; | 60 }; |
| 61 | 61 |
| 62 //////////////////////////////////////////////////////////////////////////////// /////////////////// | 62 //////////////////////////////////////////////////////////////////////////////// /////////////////// |
| 63 | 63 |
| 64 class BitmapProcShaderContext : public BitmapProcInfoContext { | 64 class BitmapProcShaderContext : public BitmapProcInfoContext { |
| 65 public: | 65 public: |
| 66 // The context takes ownership of the state. It will call its destructor | 66 // The context takes ownership of the state. It will call its destructor |
| 67 // but will NOT free the memory. | 67 // but will NOT free the memory. |
| 68 BitmapProcShaderContext(const SkShader& shader, const SkShader::ContextRec& rec, | 68 BitmapProcShaderContext(const SkShader& shader, const SkShader::ContextRec& rec, |
| 69 SkBitmapProcState* state) | 69 SkBitmapProcState* state) |
| 70 : INHERITED(shader, rec, state) | 70 : INHERITED(shader, rec, state) |
| 71 , fState(state) | 71 , fState(state) |
| 72 {} | 72 {} |
| 73 | 73 |
| 74 void shadeSpan(int x, int y, SkPMColor dstC[], int count) override { | 74 void shadeSpan(int x, int y, SkPMColor dstC[], int count) override { |
| 75 const SkBitmapProcState& state = *fState; | 75 const SkBitmapProcState& state = *fState; |
| 76 if (state.getShaderProc32()) { | 76 if (state.getShaderProc32()) { |
| 77 state.getShaderProc32()(&state, x, y, dstC, count); | 77 state.getShaderProc32()(&state, x, y, dstC, count); |
| 78 return; | 78 return; |
| 79 } | 79 } |
| 80 | 80 |
| 81 const int BUF_MAX = 128; | 81 const int BUF_MAX = 128; |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 109 return nullptr; | 109 return nullptr; |
| 110 } | 110 } |
| 111 | 111 |
| 112 private: | 112 private: |
| 113 SkBitmapProcState* fState; | 113 SkBitmapProcState* fState; |
| 114 | 114 |
| 115 typedef BitmapProcInfoContext INHERITED; | 115 typedef BitmapProcInfoContext INHERITED; |
| 116 }; | 116 }; |
| 117 | 117 |
| 118 //////////////////////////////////////////////////////////////////////////////// /////////////////// | 118 //////////////////////////////////////////////////////////////////////////////// /////////////////// |
| 119 #include "SkLinearBitmapPipeline.h" | |
| 120 #include "SkPM4f.h" | |
| 121 #include "SkXfermode.h" | |
| 122 | |
| 123 class LinearPipelineContext : public BitmapProcInfoContext { | |
| 124 public: | |
| 125 // The context takes ownership of the state. It will call its destructor | |
|
mtklein
2016/03/03 01:30:37
Having read this code, or at least in a while, it'
reed1
2016/03/03 14:05:25
Done.
| |
| 126 // but will NOT free the memory. | |
| 127 LinearPipelineContext(const SkShader& shader, const SkShader::ContextRec& re c, | |
| 128 SkBitmapProcInfo* info) | |
| 129 : INHERITED(shader, rec, info) | |
| 130 , fPipeline(info->fInvMatrix, info->fFilterQuality, info->fTileModeX, in fo->fTileModeY, | |
| 131 info->fPixmap) | |
| 132 {} | |
| 133 | |
| 134 void shadeSpan4f(int x, int y, SkPM4f dstC[], int count) override { | |
| 135 fPipeline.shadeSpan4f(x, y, dstC, count); | |
| 136 } | |
| 137 | |
| 138 void shadeSpan(int x, int y, SkPMColor dstC[], int count) override { | |
| 139 // we're not necessarily opaque, but we want the proc to treat us as if we are, so we | |
| 140 // get memcpy performance/semantics | |
|
mtklein
2016/03/03 01:30:37
remind me (or the reader) why this is okay?
reed1
2016/03/03 14:05:25
Done.
| |
| 141 auto proc = SkXfermode::GetD32Proc(nullptr, SkXfermode::kSrcIsOpaque_D32 Flag); | |
| 142 const int N = 128; | |
| 143 SkPM4f tmp[N]; | |
| 144 | |
| 145 while (count > 0) { | |
| 146 const int n = SkTMin(count, N); | |
| 147 fPipeline.shadeSpan4f(x, y, tmp, n); | |
| 148 proc(nullptr, dstC, tmp, n, nullptr); | |
| 149 dstC += n; | |
| 150 x += n; | |
| 151 count -= n; | |
| 152 } | |
| 153 } | |
| 154 | |
| 155 private: | |
| 156 SkLinearBitmapPipeline fPipeline; | |
| 157 | |
| 158 typedef BitmapProcInfoContext INHERITED; | |
| 159 }; | |
| 160 | |
| 161 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
| 119 | 162 |
| 120 size_t SkBitmapProcShader::ContextSize(const ContextRec& rec) { | 163 static bool choose_linear_pipeline(const SkShader::ContextRec& rec, const SkImag eInfo& srcInfo) { |
| 121 // The SkBitmapProcState is stored outside of the context object, with the c ontext holding | 164 // These src attributes are not supported in the new 4f context (yet) |
| 122 // a pointer to it. | 165 // |
| 123 return sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState); | 166 if (srcInfo.bytesPerPixel() < 4 || |
| 167 kRGBA_F16_SkColorType == srcInfo.colorType()) { | |
| 168 return false; | |
| 169 } | |
| 170 | |
| 171 // These src attributes are only supported in the new 4f context | |
| 172 // | |
| 173 if (srcInfo.isSRGB() || | |
| 174 kUnpremul_SkAlphaType == srcInfo.alphaType() || | |
| 175 (4 == srcInfo.bytesPerPixel() && kN32_SkColorType != srcInfo.colorType() )) | |
| 176 { | |
| 177 return true; | |
| 178 } | |
| 179 | |
| 180 // If we get here, we can reasonably use either context, respect the caller' s preference | |
| 181 // | |
| 182 return SkShader::ContextRec::kPM4f_DstType == rec.fPreferredDstType; | |
| 183 } | |
| 184 | |
| 185 size_t SkBitmapProcShader::ContextSize(const ContextRec& rec, const SkImageInfo& srcInfo) { | |
| 186 size_t size0 = sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState); | |
| 187 size_t size1 = sizeof(LinearPipelineContext) + sizeof(SkBitmapProcInfo); | |
| 188 return SkTMax(size0, size1); | |
| 124 } | 189 } |
| 125 | 190 |
| 126 SkShader::Context* SkBitmapProcShader::MakeContext(const SkShader& shader, | 191 SkShader::Context* SkBitmapProcShader::MakeContext(const SkShader& shader, |
| 127 TileMode tmx, TileMode tmy, | 192 TileMode tmx, TileMode tmy, |
| 128 const SkBitmapProvider& provi der, | 193 const SkBitmapProvider& provi der, |
| 129 const ContextRec& rec, void* storage) { | 194 const ContextRec& rec, void* storage) { |
| 130 SkMatrix totalInverse; | 195 SkMatrix totalInverse; |
| 131 // Do this first, so we know the matrix can be inverted. | 196 // Do this first, so we know the matrix can be inverted. |
| 132 if (!shader.computeTotalInverse(rec, &totalInverse)) { | 197 if (!shader.computeTotalInverse(rec, &totalInverse)) { |
| 133 return nullptr; | 198 return nullptr; |
| 134 } | 199 } |
| 135 | 200 |
| 136 void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext); | 201 // Decide if we can/want to use the new linear pipeine |
| 137 SkBitmapProcState* state = new (stateStorage) SkBitmapProcState(provider, tm x, tmy); | 202 bool useLinearPipeline = choose_linear_pipeline(rec, provider.info()); |
| 138 | 203 if (SkShader::kMirror_TileMode == tmx || SkShader::kMirror_TileMode == tmy) { |
| 139 SkASSERT(state); | 204 useLinearPipeline = false; |
| 140 if (!state->setup(totalInverse, *rec.fPaint)) { | 205 } |
| 141 state->~SkBitmapProcState(); | 206 if (totalInverse.hasPerspective()) { |
| 142 return nullptr; | 207 useLinearPipeline = false; |
| 143 } | 208 } |
| 144 | 209 |
| 145 return new (storage) BitmapProcShaderContext(shader, rec, state); | 210 if (useLinearPipeline) { |
| 211 void* infoStorage = (char*)storage + sizeof(LinearPipelineContext); | |
| 212 SkBitmapProcInfo* info = new (infoStorage) SkBitmapProcInfo(provider, tm x, tmy); | |
| 213 if (!info->init(totalInverse, *rec.fPaint)) { | |
| 214 info->~SkBitmapProcInfo(); | |
| 215 return nullptr; | |
| 216 } | |
| 217 return new (storage) LinearPipelineContext(shader, rec, info); | |
| 218 } else { | |
| 219 void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext); | |
| 220 SkBitmapProcState* state = new (stateStorage) SkBitmapProcState(provider , tmx, tmy); | |
| 221 if (!state->setup(totalInverse, *rec.fPaint)) { | |
| 222 state->~SkBitmapProcState(); | |
| 223 return nullptr; | |
| 224 } | |
| 225 return new (storage) BitmapProcShaderContext(shader, rec, state); | |
| 226 } | |
| 146 } | 227 } |
| 147 | 228 |
| 148 SkShader::Context* SkBitmapProcShader::onCreateContext(const ContextRec& rec, vo id* storage) const { | 229 SkShader::Context* SkBitmapProcShader::onCreateContext(const ContextRec& rec, vo id* storage) const { |
| 149 return MakeContext(*this, (TileMode)fTileModeX, (TileMode)fTileModeY, | 230 return MakeContext(*this, (TileMode)fTileModeX, (TileMode)fTileModeY, |
| 150 SkBitmapProvider(fRawBitmap), rec, storage); | 231 SkBitmapProvider(fRawBitmap), rec, storage); |
| 151 } | 232 } |
| 152 | 233 |
| 153 //////////////////////////////////////////////////////////////////////////////// /////////////////// | 234 //////////////////////////////////////////////////////////////////////////////// /////////////////// |
| 154 | 235 |
| 155 SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, TileMode tmx, TileMo de tmy, | 236 SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, TileMode tmx, TileMo de tmy, |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 353 inner.reset(GrSimpleTextureEffect::Create(texture, matrix, params)); | 434 inner.reset(GrSimpleTextureEffect::Create(texture, matrix, params)); |
| 354 } | 435 } |
| 355 | 436 |
| 356 if (kAlpha_8_SkColorType == fRawBitmap.colorType()) { | 437 if (kAlpha_8_SkColorType == fRawBitmap.colorType()) { |
| 357 return GrFragmentProcessor::MulOutputByInputUnpremulColor(inner); | 438 return GrFragmentProcessor::MulOutputByInputUnpremulColor(inner); |
| 358 } | 439 } |
| 359 return GrFragmentProcessor::MulOutputByInputAlpha(inner); | 440 return GrFragmentProcessor::MulOutputByInputAlpha(inner); |
| 360 } | 441 } |
| 361 | 442 |
| 362 #endif | 443 #endif |
| OLD | NEW |