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

Side by Side Diff: src/gpu/effects/GrConfigConversionEffect.cpp

Issue 1617433002: Make swizzling in read/write pixel copy code more generic (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix loop in config conversion test create Created 4 years, 11 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/gpu/effects/GrConfigConversionEffect.h ('k') | src/gpu/gl/GrGLGpu.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 2012 Google Inc. 2 * Copyright 2012 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 "GrConfigConversionEffect.h" 8 #include "GrConfigConversionEffect.h"
9 #include "GrContext.h" 9 #include "GrContext.h"
10 #include "GrDrawContext.h" 10 #include "GrDrawContext.h"
11 #include "GrInvariantOutput.h" 11 #include "GrInvariantOutput.h"
12 #include "GrSimpleTextureEffect.h" 12 #include "GrSimpleTextureEffect.h"
13 #include "SkMatrix.h" 13 #include "SkMatrix.h"
14 #include "glsl/GrGLSLFragmentProcessor.h" 14 #include "glsl/GrGLSLFragmentProcessor.h"
15 #include "glsl/GrGLSLFragmentShaderBuilder.h" 15 #include "glsl/GrGLSLFragmentShaderBuilder.h"
16 16
17 class GrGLConfigConversionEffect : public GrGLSLFragmentProcessor { 17 class GrGLConfigConversionEffect : public GrGLSLFragmentProcessor {
18 public: 18 public:
19 GrGLConfigConversionEffect(const GrProcessor& processor) { 19 GrGLConfigConversionEffect() {}
20 const GrConfigConversionEffect& configConversionEffect =
21 processor.cast<GrConfigConversionEffect>();
22 fSwapRedAndBlue = configConversionEffect.swapsRedAndBlue();
23 fPMConversion = configConversionEffect.pmConversion();
24 }
25 20
26 virtual void emitCode(EmitArgs& args) override { 21 virtual void emitCode(EmitArgs& args) override {
22 const GrConfigConversionEffect& cce = args.fFp.cast<GrConfigConversionEf fect>();
23 const GrSwizzle& swizzle = cce.swizzle();
24 GrConfigConversionEffect::PMConversion pmConversion = cce.pmConversion() ;
25
27 // Using highp for GLES here in order to avoid some precision issues on specific GPUs. 26 // Using highp for GLES here in order to avoid some precision issues on specific GPUs.
28 GrGLSLShaderVar tmpVar("tmpColor", kVec4f_GrSLType, 0, kHigh_GrSLPrecisi on); 27 GrGLSLShaderVar tmpVar("tmpColor", kVec4f_GrSLType, 0, kHigh_GrSLPrecisi on);
29 SkString tmpDecl; 28 SkString tmpDecl;
30 tmpVar.appendDecl(args.fGLSLCaps, &tmpDecl); 29 tmpVar.appendDecl(args.fGLSLCaps, &tmpDecl);
31 30
32 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; 31 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
33 32
34 fragBuilder->codeAppendf("%s;", tmpDecl.c_str()); 33 fragBuilder->codeAppendf("%s;", tmpDecl.c_str());
35 34
36 fragBuilder->codeAppendf("%s = ", tmpVar.c_str()); 35 fragBuilder->codeAppendf("%s = ", tmpVar.c_str());
37 fragBuilder->appendTextureLookup(args.fSamplers[0], args.fCoords[0].c_st r(), 36 fragBuilder->appendTextureLookup(args.fSamplers[0], args.fCoords[0].c_st r(),
38 args.fCoords[0].getType()); 37 args.fCoords[0].getType());
39 fragBuilder->codeAppend(";"); 38 fragBuilder->codeAppend(";");
40 39
41 if (GrConfigConversionEffect::kNone_PMConversion == fPMConversion) { 40 if (GrConfigConversionEffect::kNone_PMConversion == pmConversion) {
42 SkASSERT(fSwapRedAndBlue); 41 SkASSERT(GrSwizzle::RGBA() != swizzle);
43 fragBuilder->codeAppendf("%s = %s.bgra;", args.fOutputColor, tmpVar. c_str()); 42 fragBuilder->codeAppendf("%s = %s.%s;", args.fOutputColor, tmpVar.c_ str(),
43 swizzle.c_str());
44 } else { 44 } else {
45 const char* swiz = fSwapRedAndBlue ? "bgr" : "rgb"; 45 switch (pmConversion) {
46 switch (fPMConversion) {
47 case GrConfigConversionEffect::kMulByAlpha_RoundUp_PMConversion: 46 case GrConfigConversionEffect::kMulByAlpha_RoundUp_PMConversion:
48 fragBuilder->codeAppendf( 47 fragBuilder->codeAppendf(
49 "%s = vec4(ceil(%s.%s * %s.a * 255.0) / 255.0, %s.a);", 48 "%s = vec4(ceil(%s.rgb * %s.a * 255.0) / 255.0, %s.a);",
50 tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tm pVar.c_str()); 49 tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), tmpVar.c _str());
51 break; 50 break;
52 case GrConfigConversionEffect::kMulByAlpha_RoundDown_PMConversio n: 51 case GrConfigConversionEffect::kMulByAlpha_RoundDown_PMConversio n:
53 // Add a compensation(0.001) here to avoid the side effect o f the floor operation. 52 // Add a compensation(0.001) here to avoid the side effect o f the floor operation.
54 // In Intel GPUs, the integer value converted from floor(%s. r * 255.0) / 255.0 53 // In Intel GPUs, the integer value converted from floor(%s. r * 255.0) / 255.0
55 // is less than the integer value converted from %s.r by 1 when the %s.r is 54 // is less than the integer value converted from %s.r by 1 when the %s.r is
56 // converted from the integer value 2^n, such as 1, 2, 4, 8, etc. 55 // converted from the integer value 2^n, such as 1, 2, 4, 8, etc.
57 fragBuilder->codeAppendf( 56 fragBuilder->codeAppendf(
58 "%s = vec4(floor(%s.%s * %s.a * 255.0 + 0.001) / 255.0, %s.a);", 57 "%s = vec4(floor(%s.rgb * %s.a * 255.0 + 0.001) / 255.0, %s.a);",
59 tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tm pVar.c_str()); 58 tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), tmpVar.c _str());
59
60 break; 60 break;
61 case GrConfigConversionEffect::kDivByAlpha_RoundUp_PMConversion: 61 case GrConfigConversionEffect::kDivByAlpha_RoundUp_PMConversion:
62 fragBuilder->codeAppendf( 62 fragBuilder->codeAppendf(
63 "%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(ceil(%s.%s / %s .a * 255.0) / 255.0, %s.a);", 63 "%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(ceil(%s.rgb / % s.a * 255.0) / 255.0, %s.a);",
64 tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), swiz, tm pVar.c_str(), tmpVar.c_str()); 64 tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), tmpVar.c _str(),
65 tmpVar.c_str());
65 break; 66 break;
66 case GrConfigConversionEffect::kDivByAlpha_RoundDown_PMConversio n: 67 case GrConfigConversionEffect::kDivByAlpha_RoundDown_PMConversio n:
67 fragBuilder->codeAppendf( 68 fragBuilder->codeAppendf(
68 "%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(floor(%s.%s / % s.a * 255.0) / 255.0, %s.a);", 69 "%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(floor(%s.rgb / %s.a * 255.0) / 255.0, %s.a);",
69 tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), swiz, tm pVar.c_str(), tmpVar.c_str()); 70 tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), tmpVar.c _str(),
71 tmpVar.c_str());
70 break; 72 break;
71 default: 73 default:
72 SkFAIL("Unknown conversion op."); 74 SkFAIL("Unknown conversion op.");
73 break; 75 break;
74 } 76 }
75 fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, tmpVar.c_str ()); 77 fragBuilder->codeAppendf("%s = %s.%s;", args.fOutputColor, tmpVar.c_ str(),
78 swizzle.c_str());
76 } 79 }
77 SkString modulate; 80 SkString modulate;
78 GrGLSLMulVarBy4f(&modulate, args.fOutputColor, args.fInputColor); 81 GrGLSLMulVarBy4f(&modulate, args.fOutputColor, args.fInputColor);
79 fragBuilder->codeAppend(modulate.c_str()); 82 fragBuilder->codeAppend(modulate.c_str());
80 } 83 }
81 84
82 static inline void GenKey(const GrProcessor& processor, const GrGLSLCaps&, 85 static inline void GenKey(const GrProcessor& processor, const GrGLSLCaps&,
83 GrProcessorKeyBuilder* b) { 86 GrProcessorKeyBuilder* b) {
84 const GrConfigConversionEffect& conv = processor.cast<GrConfigConversion Effect>(); 87 const GrConfigConversionEffect& cce = processor.cast<GrConfigConversionE ffect>();
85 uint32_t key = (conv.swapsRedAndBlue() ? 0 : 1) | (conv.pmConversion() < < 1); 88 uint32_t key = (cce.swizzle().asKey()) | (cce.pmConversion() << 16);
86 b->add32(key); 89 b->add32(key);
87 } 90 }
88 91
89 private: 92 private:
90 bool fSwapRedAndBlue;
91 GrConfigConversionEffect::PMConversion fPMConversion;
92
93 typedef GrGLSLFragmentProcessor INHERITED; 93 typedef GrGLSLFragmentProcessor INHERITED;
94 94
95 }; 95 };
96 96
97 /////////////////////////////////////////////////////////////////////////////// 97 ///////////////////////////////////////////////////////////////////////////////
98 98
99 GrConfigConversionEffect::GrConfigConversionEffect(GrTexture* texture, 99 GrConfigConversionEffect::GrConfigConversionEffect(GrTexture* texture,
100 bool swapRedAndBlue, 100 const GrSwizzle& swizzle,
101 PMConversion pmConversion, 101 PMConversion pmConversion,
102 const SkMatrix& matrix) 102 const SkMatrix& matrix)
103 : INHERITED(texture, matrix) 103 : INHERITED(texture, matrix)
104 , fSwapRedAndBlue(swapRedAndBlue) 104 , fSwizzle(swizzle)
105 , fPMConversion(pmConversion) { 105 , fPMConversion(pmConversion) {
106 this->initClassID<GrConfigConversionEffect>(); 106 this->initClassID<GrConfigConversionEffect>();
107 // We expect to get here with non-BGRA/RGBA only if we're doing not doing a premul/unpremul 107 // We expect to get here with non-BGRA/RGBA only if we're doing not doing a premul/unpremul
108 // conversion. 108 // conversion.
109 SkASSERT((kRGBA_8888_GrPixelConfig == texture->config() || 109 SkASSERT((kRGBA_8888_GrPixelConfig == texture->config() ||
110 kBGRA_8888_GrPixelConfig == texture->config()) || 110 kBGRA_8888_GrPixelConfig == texture->config()) ||
111 kNone_PMConversion == pmConversion); 111 kNone_PMConversion == pmConversion);
112 // Why did we pollute our texture cache instead of using a GrSingleTextureEf fect? 112 // Why did we pollute our texture cache instead of using a GrSingleTextureEf fect?
113 SkASSERT(swapRedAndBlue || kNone_PMConversion != pmConversion); 113 SkASSERT(swizzle != GrSwizzle::RGBA() || kNone_PMConversion != pmConversion) ;
114 } 114 }
115 115
116 bool GrConfigConversionEffect::onIsEqual(const GrFragmentProcessor& s) const { 116 bool GrConfigConversionEffect::onIsEqual(const GrFragmentProcessor& s) const {
117 const GrConfigConversionEffect& other = s.cast<GrConfigConversionEffect>(); 117 const GrConfigConversionEffect& other = s.cast<GrConfigConversionEffect>();
118 return other.fSwapRedAndBlue == fSwapRedAndBlue && 118 return other.fSwizzle == fSwizzle &&
119 other.fPMConversion == fPMConversion; 119 other.fPMConversion == fPMConversion;
120 } 120 }
121 121
122 void GrConfigConversionEffect::onComputeInvariantOutput(GrInvariantOutput* inout ) const { 122 void GrConfigConversionEffect::onComputeInvariantOutput(GrInvariantOutput* inout ) const {
123 this->updateInvariantOutputForModulation(inout); 123 this->updateInvariantOutputForModulation(inout);
124 } 124 }
125 125
126 /////////////////////////////////////////////////////////////////////////////// 126 ///////////////////////////////////////////////////////////////////////////////
127 127
128 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConfigConversionEffect); 128 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConfigConversionEffect);
129 129
130 const GrFragmentProcessor* GrConfigConversionEffect::TestCreate(GrProcessorTestD ata* d) { 130 const GrFragmentProcessor* GrConfigConversionEffect::TestCreate(GrProcessorTestD ata* d) {
131 PMConversion pmConv = static_cast<PMConversion>(d->fRandom->nextULessThan(kP MConversionCnt)); 131 PMConversion pmConv = static_cast<PMConversion>(d->fRandom->nextULessThan(kP MConversionCnt));
132 bool swapRB; 132 GrSwizzle swizzle;
133 if (kNone_PMConversion == pmConv) { 133 do {
134 swapRB = true; 134 swizzle = GrSwizzle::CreateRandom(d->fRandom);
135 } else { 135 } while (pmConv == kNone_PMConversion && swizzle == GrSwizzle::RGBA());
136 swapRB = d->fRandom->nextBool();
137 }
138 return new GrConfigConversionEffect(d->fTextures[GrProcessorUnitTest::kSkiaP MTextureIdx], 136 return new GrConfigConversionEffect(d->fTextures[GrProcessorUnitTest::kSkiaP MTextureIdx],
139 swapRB, pmConv, GrTest::TestMatrix(d->fR andom)); 137 swizzle, pmConv, GrTest::TestMatrix(d->f Random));
140 } 138 }
141 139
142 /////////////////////////////////////////////////////////////////////////////// 140 ///////////////////////////////////////////////////////////////////////////////
143 141
144 void GrConfigConversionEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps, 142 void GrConfigConversionEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps,
145 GrProcessorKeyBuilder* b) c onst { 143 GrProcessorKeyBuilder* b) c onst {
146 GrGLConfigConversionEffect::GenKey(*this, caps, b); 144 GrGLConfigConversionEffect::GenKey(*this, caps, b);
147 } 145 }
148 146
149 GrGLSLFragmentProcessor* GrConfigConversionEffect::onCreateGLSLInstance() const { 147 GrGLSLFragmentProcessor* GrConfigConversionEffect::onCreateGLSLInstance() const {
150 return new GrGLConfigConversionEffect(*this); 148 return new GrGLConfigConversionEffect();
151 } 149 }
152 150
153 151
154 152
155 void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context , 153 void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context ,
156 PMConversion* pmTo UPMRule, 154 PMConversion* pmTo UPMRule,
157 PMConversion* upmT oPMRule) { 155 PMConversion* upmT oPMRule) {
158 *pmToUPMRule = kNone_PMConversion; 156 *pmToUPMRule = kNone_PMConversion;
159 *upmToPMRule = kNone_PMConversion; 157 *upmToPMRule = kNone_PMConversion;
160 SkAutoTMalloc<uint32_t> data(256 * 256 * 3); 158 SkAutoTMalloc<uint32_t> data(256 * 256 * 3);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 static const SkRect kDstRect = SkRect::MakeWH(SkIntToScalar(256), SkIntT oScalar(256)); 206 static const SkRect kDstRect = SkRect::MakeWH(SkIntToScalar(256), SkIntT oScalar(256));
209 static const SkRect kSrcRect = SkRect::MakeWH(SK_Scalar1, SK_Scalar1); 207 static const SkRect kSrcRect = SkRect::MakeWH(SK_Scalar1, SK_Scalar1);
210 // We do a PM->UPM draw from dataTex to readTex and read the data. Then we do a UPM->PM draw 208 // We do a PM->UPM draw from dataTex to readTex and read the data. Then we do a UPM->PM draw
211 // from readTex to tempTex followed by a PM->UPM draw to readTex and fin ally read the data. 209 // from readTex to tempTex followed by a PM->UPM draw to readTex and fin ally read the data.
212 // We then verify that two reads produced the same values. 210 // We then verify that two reads produced the same values.
213 211
214 GrPaint paint1; 212 GrPaint paint1;
215 GrPaint paint2; 213 GrPaint paint2;
216 GrPaint paint3; 214 GrPaint paint3;
217 SkAutoTUnref<GrFragmentProcessor> pmToUPM1(new GrConfigConversionEffect( 215 SkAutoTUnref<GrFragmentProcessor> pmToUPM1(new GrConfigConversionEffect(
218 dataTex, false, *pmToUPMRule, SkMatrix::I())); 216 dataTex, GrSwizzle::RGBA(), *pmToUPMRule, SkMatrix::I()));
219 SkAutoTUnref<GrFragmentProcessor> upmToPM(new GrConfigConversionEffect( 217 SkAutoTUnref<GrFragmentProcessor> upmToPM(new GrConfigConversionEffect(
220 readTex, false, *upmToPMRule, SkMatrix::I())); 218 readTex, GrSwizzle::RGBA(), *upmToPMRule, SkMatrix::I()));
221 SkAutoTUnref<GrFragmentProcessor> pmToUPM2(new GrConfigConversionEffect( 219 SkAutoTUnref<GrFragmentProcessor> pmToUPM2(new GrConfigConversionEffect(
222 tempTex, false, *pmToUPMRule, SkMatrix::I())); 220 tempTex, GrSwizzle::RGBA(), *pmToUPMRule, SkMatrix::I()));
223 221
224 paint1.addColorFragmentProcessor(pmToUPM1); 222 paint1.addColorFragmentProcessor(pmToUPM1);
225 paint1.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); 223 paint1.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
226 224
227 225
228 SkAutoTUnref<GrDrawContext> readDrawContext( 226 SkAutoTUnref<GrDrawContext> readDrawContext(
229 context->drawContext(readTex->asRenderTarget ())); 227 context->drawContext(readTex->asRenderTarget ()));
230 if (!readDrawContext) { 228 if (!readDrawContext) {
231 failed = true; 229 failed = true;
232 break; 230 break;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 } 280 }
283 } 281 }
284 } 282 }
285 if (failed) { 283 if (failed) {
286 *pmToUPMRule = kNone_PMConversion; 284 *pmToUPMRule = kNone_PMConversion;
287 *upmToPMRule = kNone_PMConversion; 285 *upmToPMRule = kNone_PMConversion;
288 } 286 }
289 } 287 }
290 288
291 const GrFragmentProcessor* GrConfigConversionEffect::Create(GrTexture* texture, 289 const GrFragmentProcessor* GrConfigConversionEffect::Create(GrTexture* texture,
292 bool swapRedAndBlue, 290 const GrSwizzle& swi zzle,
293 PMConversion pmConve rsion, 291 PMConversion pmConve rsion,
294 const SkMatrix& matr ix) { 292 const SkMatrix& matr ix) {
295 if (!swapRedAndBlue && kNone_PMConversion == pmConversion) { 293 if (swizzle == GrSwizzle::RGBA() && kNone_PMConversion == pmConversion) {
296 // If we returned a GrConfigConversionEffect that was equivalent to a Gr SimpleTextureEffect 294 // If we returned a GrConfigConversionEffect that was equivalent to a Gr SimpleTextureEffect
297 // then we may pollute our texture cache with redundant shaders. So in t he case that no 295 // then we may pollute our texture cache with redundant shaders. So in t he case that no
298 // conversions were requested we instead return a GrSimpleTextureEffect. 296 // conversions were requested we instead return a GrSimpleTextureEffect.
299 return GrSimpleTextureEffect::Create(texture, matrix); 297 return GrSimpleTextureEffect::Create(texture, matrix);
300 } else { 298 } else {
301 if (kRGBA_8888_GrPixelConfig != texture->config() && 299 if (kRGBA_8888_GrPixelConfig != texture->config() &&
302 kBGRA_8888_GrPixelConfig != texture->config() && 300 kBGRA_8888_GrPixelConfig != texture->config() &&
303 kNone_PMConversion != pmConversion) { 301 kNone_PMConversion != pmConversion) {
304 // The PM conversions assume colors are 0..255 302 // The PM conversions assume colors are 0..255
305 return nullptr; 303 return nullptr;
306 } 304 }
307 return new GrConfigConversionEffect(texture, swapRedAndBlue, pmConversio n, matrix); 305 return new GrConfigConversionEffect(texture, swizzle, pmConversion, matr ix);
308 } 306 }
309 } 307 }
OLDNEW
« no previous file with comments | « src/gpu/effects/GrConfigConversionEffect.h ('k') | src/gpu/gl/GrGLGpu.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698