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

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

Issue 1760123003: Add support for new bitmapshader context (patchset #5 id:80001 of https://codereview.chromium.org/1… (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: add dox Created 4 years, 9 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
« no previous file with comments | « src/core/SkBitmapProcShader.h ('k') | src/image/SkImageShader.cpp » ('j') | 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 * 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"
11 #include "SkColorPriv.h" 11 #include "SkColorPriv.h"
12 #include "SkErrorInternals.h" 12 #include "SkErrorInternals.h"
13 #include "SkPixelRef.h" 13 #include "SkPixelRef.h"
14 #include "SkReadBuffer.h" 14 #include "SkReadBuffer.h"
15 #include "SkWriteBuffer.h" 15 #include "SkWriteBuffer.h"
16 16
17 #if SK_SUPPORT_GPU 17 #if SK_SUPPORT_GPU
18 #include "SkGrPriv.h" 18 #include "SkGrPriv.h"
19 #include "effects/GrBicubicEffect.h" 19 #include "effects/GrBicubicEffect.h"
20 #include "effects/GrSimpleTextureEffect.h" 20 #include "effects/GrSimpleTextureEffect.h"
21 #endif 21 #endif
22 22
23 static bool only_scale_and_translate(const SkMatrix& matrix) { 23 static bool only_scale_and_translate(const SkMatrix& matrix) {
24 unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask; 24 unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask;
25 return (matrix.getType() & ~mask) == 0; 25 return (matrix.getType() & ~mask) == 0;
26 } 26 }
27 27
28 class BitmapProcInfoContext : public SkShader::Context { 28 class BitmapProcInfoContext : public SkShader::Context {
29 public: 29 public:
30 // The context takes ownership of the info. It will call its destructor 30 // The info has been allocated elsewhere, but we are responsible for calling its destructor.
31 // but will NOT free the memory.
32 BitmapProcInfoContext(const SkShader& shader, const SkShader::ContextRec& re c, 31 BitmapProcInfoContext(const SkShader& shader, const SkShader::ContextRec& re c,
33 SkBitmapProcInfo* info) 32 SkBitmapProcInfo* info)
34 : INHERITED(shader, rec) 33 : INHERITED(shader, rec)
35 , fInfo(info) 34 , fInfo(info)
36 { 35 {
37 fFlags = 0; 36 fFlags = 0;
38 if (fInfo->fPixmap.isOpaque() && (255 == this->getPaintAlpha())) { 37 if (fInfo->fPixmap.isOpaque() && (255 == this->getPaintAlpha())) {
39 fFlags |= SkShader::kOpaqueAlpha_Flag; 38 fFlags |= SkShader::kOpaqueAlpha_Flag;
40 } 39 }
41 40
42 if (1 == fInfo->fPixmap.height() && only_scale_and_translate(this->getTo talInverse())) { 41 if (1 == fInfo->fPixmap.height() && only_scale_and_translate(this->getTo talInverse())) {
43 fFlags |= SkShader::kConstInY32_Flag; 42 fFlags |= SkShader::kConstInY32_Flag;
44 } 43 }
45 } 44 }
46 45
47 ~BitmapProcInfoContext() override { 46 ~BitmapProcInfoContext() override {
48 // The bitmap proc state has been created outside of the context on memo ry that will be freed
49 // elsewhere. Only call the destructor but leave the freeing of the memo ry to the caller.
50 fInfo->~SkBitmapProcInfo(); 47 fInfo->~SkBitmapProcInfo();
51 } 48 }
52 49
53 uint32_t getFlags() const override { return fFlags; } 50 uint32_t getFlags() const override { return fFlags; }
54 51
55 private: 52 private:
56 SkBitmapProcInfo* fInfo; 53 SkBitmapProcInfo* fInfo;
57 uint32_t fFlags; 54 uint32_t fFlags;
58 55
59 typedef SkShader::Context INHERITED; 56 typedef SkShader::Context INHERITED;
60 }; 57 };
61 58
62 //////////////////////////////////////////////////////////////////////////////// /////////////////// 59 //////////////////////////////////////////////////////////////////////////////// ///////////////////
63 60
64 class BitmapProcShaderContext : public BitmapProcInfoContext { 61 class BitmapProcShaderContext : public BitmapProcInfoContext {
65 public: 62 public:
66 // The context takes ownership of the state. It will call its destructor
67 // but will NOT free the memory.
68 BitmapProcShaderContext(const SkShader& shader, const SkShader::ContextRec& rec, 63 BitmapProcShaderContext(const SkShader& shader, const SkShader::ContextRec& rec,
69 SkBitmapProcState* state) 64 SkBitmapProcState* state)
70 : INHERITED(shader, rec, state) 65 : INHERITED(shader, rec, state)
71 , fState(state) 66 , fState(state)
72 {} 67 {}
73 68
74 void shadeSpan(int x, int y, SkPMColor dstC[], int count) override { 69 void shadeSpan(int x, int y, SkPMColor dstC[], int count) override {
75 const SkBitmapProcState& state = *fState; 70 const SkBitmapProcState& state = *fState;
76 if (state.getShaderProc32()) { 71 if (state.getShaderProc32()) {
77 state.getShaderProc32()(&state, x, y, dstC, count); 72 state.getShaderProc32()(&state, x, y, dstC, count);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 return nullptr; 104 return nullptr;
110 } 105 }
111 106
112 private: 107 private:
113 SkBitmapProcState* fState; 108 SkBitmapProcState* fState;
114 109
115 typedef BitmapProcInfoContext INHERITED; 110 typedef BitmapProcInfoContext INHERITED;
116 }; 111 };
117 112
118 //////////////////////////////////////////////////////////////////////////////// /////////////////// 113 //////////////////////////////////////////////////////////////////////////////// ///////////////////
114 #include "SkLinearBitmapPipeline.h"
115 #include "SkPM4f.h"
116 #include "SkXfermode.h"
117
118 class LinearPipelineContext : public BitmapProcInfoContext {
119 public:
120 LinearPipelineContext(const SkShader& shader, const SkShader::ContextRec& re c,
121 SkBitmapProcInfo* info)
122 : INHERITED(shader, rec, info)
123 {
124 // Need to ensure that our pipeline is created at a 16byte aligned addre ss
125 fPipeline = (SkLinearBitmapPipeline*)SkAlign16((intptr_t)fStorage);
126 new (fPipeline) SkLinearBitmapPipeline(info->fInvMatrix, info->fFilterQu ality,
127 info->fTileModeX, info->fTileMode Y,
128 info->fPixmap);
129
130 // To implement the old shadeSpan entry-point, we need to efficiently co nvert our native
131 // floats into SkPMColor. The SkXfermode::D32Procs do exactly that.
132 //
133 sk_sp<SkXfermode> xfer(SkXfermode::Create(SkXfermode::kSrc_Mode));
134 fXferProc = SkXfermode::GetD32Proc(xfer.get(), 0);
135 }
136
137 ~LinearPipelineContext() override {
138 // since we did a manual new, we need to manually destroy as well.
139 fPipeline->~SkLinearBitmapPipeline();
140 }
141
142 void shadeSpan4f(int x, int y, SkPM4f dstC[], int count) override {
143 fPipeline->shadeSpan4f(x, y, dstC, count);
144 }
145
146 void shadeSpan(int x, int y, SkPMColor dstC[], int count) override {
147 const int N = 128;
148 SkPM4f tmp[N];
149
150 while (count > 0) {
151 const int n = SkTMin(count, N);
152 fPipeline->shadeSpan4f(x, y, tmp, n);
153 fXferProc(nullptr, dstC, tmp, n, nullptr);
154 dstC += n;
155 x += n;
156 count -= n;
157 }
158 }
159
160 private:
161 enum {
162 kActualSize = sizeof(SkLinearBitmapPipeline),
163 kPaddedSize = SkAlignPtr(kActualSize + 12),
164 };
165 void* fStorage[kPaddedSize / sizeof(void*)];
166 SkLinearBitmapPipeline* fPipeline;
167 SkXfermode::D32Proc fXferProc;
168
169 typedef BitmapProcInfoContext INHERITED;
170 };
171
172 //////////////////////////////////////////////////////////////////////////////// ///////////////////
119 173
120 size_t SkBitmapProcShader::ContextSize(const ContextRec& rec) { 174 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 175 // These src attributes are not supported in the new 4f context (yet)
122 // a pointer to it. 176 //
123 return sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState); 177 if (srcInfo.bytesPerPixel() < 4 ||
178 kRGBA_F16_SkColorType == srcInfo.colorType()) {
179 return false;
180 }
181
182 #if 0 // later we may opt-in to the new code even if the client hasn't request ed it...
183 // These src attributes are only supported in the new 4f context
184 //
185 if (srcInfo.isSRGB() ||
186 kUnpremul_SkAlphaType == srcInfo.alphaType() ||
187 (4 == srcInfo.bytesPerPixel() && kN32_SkColorType != srcInfo.colorType() ))
188 {
189 return true;
190 }
191 #endif
192
193 // If we get here, we can reasonably use either context, respect the caller' s preference
194 //
195 return SkShader::ContextRec::kPM4f_DstType == rec.fPreferredDstType;
196 }
197
198 size_t SkBitmapProcShader::ContextSize(const ContextRec& rec, const SkImageInfo& srcInfo) {
199 size_t size0 = sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState);
200 size_t size1 = sizeof(LinearPipelineContext) + sizeof(SkBitmapProcInfo);
201 return SkTMax(size0, size1);
124 } 202 }
125 203
126 SkShader::Context* SkBitmapProcShader::MakeContext(const SkShader& shader, 204 SkShader::Context* SkBitmapProcShader::MakeContext(const SkShader& shader,
127 TileMode tmx, TileMode tmy, 205 TileMode tmx, TileMode tmy,
128 const SkBitmapProvider& provi der, 206 const SkBitmapProvider& provi der,
129 const ContextRec& rec, void* storage) { 207 const ContextRec& rec, void* storage) {
130 SkMatrix totalInverse; 208 SkMatrix totalInverse;
131 // Do this first, so we know the matrix can be inverted. 209 // Do this first, so we know the matrix can be inverted.
132 if (!shader.computeTotalInverse(rec, &totalInverse)) { 210 if (!shader.computeTotalInverse(rec, &totalInverse)) {
133 return nullptr; 211 return nullptr;
134 } 212 }
135 213
136 void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext); 214 // Decide if we can/want to use the new linear pipeine
137 SkBitmapProcState* state = new (stateStorage) SkBitmapProcState(provider, tm x, tmy); 215 bool useLinearPipeline = choose_linear_pipeline(rec, provider.info());
138 216
139 SkASSERT(state); 217 // New code doesn't support Mirror (YET), so we detect that here.
140 if (!state->setup(totalInverse, *rec.fPaint)) { 218 //
141 state->~SkBitmapProcState(); 219 if (SkShader::kMirror_TileMode == tmx || SkShader::kMirror_TileMode == tmy) {
142 return nullptr; 220 useLinearPipeline = false;
143 } 221 }
144 222
145 return new (storage) BitmapProcShaderContext(shader, rec, state); 223 // New code doesn't support Mirror (YET), so we detect that here.
224 //
225 if (totalInverse.hasPerspective()) {
226 useLinearPipeline = false;
227 }
228
229 if (useLinearPipeline) {
230 void* infoStorage = (char*)storage + sizeof(LinearPipelineContext);
231 SkBitmapProcInfo* info = new (infoStorage) SkBitmapProcInfo(provider, tm x, tmy);
232 if (!info->init(totalInverse, *rec.fPaint)) {
233 info->~SkBitmapProcInfo();
234 return nullptr;
235 }
236 return new (storage) LinearPipelineContext(shader, rec, info);
237 } else {
238 void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext);
239 SkBitmapProcState* state = new (stateStorage) SkBitmapProcState(provider , tmx, tmy);
240 if (!state->setup(totalInverse, *rec.fPaint)) {
241 state->~SkBitmapProcState();
242 return nullptr;
243 }
244 return new (storage) BitmapProcShaderContext(shader, rec, state);
245 }
146 } 246 }
147 247
148 SkShader::Context* SkBitmapProcShader::onCreateContext(const ContextRec& rec, vo id* storage) const { 248 SkShader::Context* SkBitmapProcShader::onCreateContext(const ContextRec& rec, vo id* storage) const {
149 return MakeContext(*this, (TileMode)fTileModeX, (TileMode)fTileModeY, 249 return MakeContext(*this, (TileMode)fTileModeX, (TileMode)fTileModeY,
150 SkBitmapProvider(fRawBitmap), rec, storage); 250 SkBitmapProvider(fRawBitmap), rec, storage);
151 } 251 }
152 252
153 //////////////////////////////////////////////////////////////////////////////// /////////////////// 253 //////////////////////////////////////////////////////////////////////////////// ///////////////////
154 254
155 SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, TileMode tmx, TileMo de tmy, 255 SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, TileMode tmx, TileMo de tmy,
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 inner.reset(GrSimpleTextureEffect::Create(texture, matrix, params)); 453 inner.reset(GrSimpleTextureEffect::Create(texture, matrix, params));
354 } 454 }
355 455
356 if (kAlpha_8_SkColorType == fRawBitmap.colorType()) { 456 if (kAlpha_8_SkColorType == fRawBitmap.colorType()) {
357 return GrFragmentProcessor::MulOutputByInputUnpremulColor(inner); 457 return GrFragmentProcessor::MulOutputByInputUnpremulColor(inner);
358 } 458 }
359 return GrFragmentProcessor::MulOutputByInputAlpha(inner); 459 return GrFragmentProcessor::MulOutputByInputAlpha(inner);
360 } 460 }
361 461
362 #endif 462 #endif
OLDNEW
« no previous file with comments | « src/core/SkBitmapProcShader.h ('k') | src/image/SkImageShader.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698