1 /* 2 * Copyright 2018 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 /************************************************************************************************** 9 *** This file was autogenerated from GrConfigConversionEffect.fp; do not modify. 10 **************************************************************************************************/ 11 #ifndef GrConfigConversionEffect_DEFINED 12 #define GrConfigConversionEffect_DEFINED 13 #include "SkTypes.h" 14 #if SK_SUPPORT_GPU 15 16 #include "GrClip.h" 17 #include "GrContext.h" 18 #include "GrContextPriv.h" 19 #include "GrProxyProvider.h" 20 #include "GrRenderTargetContext.h" 21 #include "GrFragmentProcessor.h" 22 #include "GrCoordTransform.h" 23 class GrConfigConversionEffect : public GrFragmentProcessor { 24 public: 25 static bool TestForPreservingPMConversions(GrContext* context) { 26 static constexpr int kSize = 256; 27 static constexpr GrPixelConfig kConfig = kRGBA_8888_GrPixelConfig; 28 SkAutoTMalloc<uint32_t> data(kSize * kSize * 3); 29 uint32_t* srcData = data.get(); 30 uint32_t* firstRead = data.get() + kSize * kSize; 31 uint32_t* secondRead = data.get() + 2 * kSize * kSize; 32 33 // Fill with every possible premultiplied A, color channel value. There will be 256-y 34 // duplicate values in row y. We set r, g, and b to the same value since they are handled 35 // identically. 36 for (int y = 0; y < kSize; ++y) { 37 for (int x = 0; x < kSize; ++x) { 38 uint8_t* color = reinterpret_cast<uint8_t*>(&srcData[kSize * y + x]); 39 color[3] = y; 40 color[2] = SkTMin(x, y); 41 color[1] = SkTMin(x, y); 42 color[0] = SkTMin(x, y); 43 } 44 } 45 46 const SkImageInfo ii = 47 SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType); 48 49 sk_sp<GrRenderTargetContext> readRTC(context->makeDeferredRenderTargetContext( 50 SkBackingFit::kExact, kSize, kSize, kConfig, nullptr)); 51 sk_sp<GrRenderTargetContext> tempRTC(context->makeDeferredRenderTargetContext( 52 SkBackingFit::kExact, kSize, kSize, kConfig, nullptr)); 53 if (!readRTC || !readRTC->asTextureProxy() || !tempRTC) { 54 return false; 55 } 56 // Adding discard to appease vulkan validation warning about loading uninitialized data on 57 // draw 58 readRTC->discard(); 59 60 GrSurfaceDesc desc; 61 desc.fOrigin = kTopLeft_GrSurfaceOrigin; 62 desc.fWidth = kSize; 63 desc.fHeight = kSize; 64 desc.fConfig = kConfig; 65 66 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider(); 67 68 sk_sp<GrTextureProxy> dataProxy = 69 proxyProvider->createTextureProxy(desc, SkBudgeted::kYes, data, 0); 70 if (!dataProxy) { 71 return false; 72 } 73 74 static const SkRect kRect = SkRect::MakeIWH(kSize, kSize); 75 76 // We do a PM->UPM draw from dataTex to readTex and read the data. Then we do a UPM->PM draw 77 // from readTex to tempTex followed by a PM->UPM draw to readTex and finally read the data. 78 // We then verify that two reads produced the same values. 79 80 GrPaint paint1; 81 GrPaint paint2; 82 GrPaint paint3; 83 std::unique_ptr<GrFragmentProcessor> pmToUPM( 84 new GrConfigConversionEffect(PMConversion::kToUnpremul)); 85 std::unique_ptr<GrFragmentProcessor> upmToPM( 86 new GrConfigConversionEffect(PMConversion::kToPremul)); 87 88 paint1.addColorTextureProcessor(dataProxy, SkMatrix::I()); 89 paint1.addColorFragmentProcessor(pmToUPM->clone()); 90 paint1.setPorterDuffXPFactory(SkBlendMode::kSrc); 91 92 readRTC->fillRectToRect(GrNoClip(), std::move(paint1), GrAA::kNo, SkMatrix::I(), kRect, 93 kRect); 94 if (!readRTC->readPixels(ii, firstRead, 0, 0, 0)) { 95 return false; 96 } 97 98 // Adding discard to appease vulkan validation warning about loading uninitialized data on 99 // draw 100 tempRTC->discard(); 101 102 paint2.addColorTextureProcessor(readRTC->asTextureProxyRef(), SkMatrix::I()); 103 paint2.addColorFragmentProcessor(std::move(upmToPM)); 104 paint2.setPorterDuffXPFactory(SkBlendMode::kSrc); 105 106 tempRTC->fillRectToRect(GrNoClip(), std::move(paint2), GrAA::kNo, SkMatrix::I(), kRect, 107 kRect); 108 109 paint3.addColorTextureProcessor(tempRTC->asTextureProxyRef(), SkMatrix::I()); 110 paint3.addColorFragmentProcessor(std::move(pmToUPM)); 111 paint3.setPorterDuffXPFactory(SkBlendMode::kSrc); 112 113 readRTC->fillRectToRect(GrNoClip(), std::move(paint3), GrAA::kNo, SkMatrix::I(), kRect, 114 kRect); 115 116 if (!readRTC->readPixels(ii, secondRead, 0, 0, 0)) { 117 return false; 118 } 119 120 for (int y = 0; y < kSize; ++y) { 121 for (int x = 0; x <= y; ++x) { 122 if (firstRead[kSize * y + x] != secondRead[kSize * y + x]) { 123 return false; 124 } 125 } 126 } 127 128 return true; 129 } 130 PMConversion pmConversion() const { return fPmConversion; } 131 132 static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp, 133 PMConversion pmConversion) { 134 if (!fp) { 135 return nullptr; 136 } 137 std::unique_ptr<GrFragmentProcessor> ccFP(new GrConfigConversionEffect(pmConversion)); 138 std::unique_ptr<GrFragmentProcessor> fpPipeline[] = {std::move(fp), std::move(ccFP)}; 139 return GrFragmentProcessor::RunInSeries(fpPipeline, 2); 140 } 141 GrConfigConversionEffect(const GrConfigConversionEffect& src); 142 std::unique_ptr<GrFragmentProcessor> clone() const override; 143 const char* name() const override { return "ConfigConversionEffect"; } 144 145 private: 146 GrConfigConversionEffect(PMConversion pmConversion) 147 : INHERITED(kGrConfigConversionEffect_ClassID, kNone_OptimizationFlags) 148 , fPmConversion(pmConversion) {} 149 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; 150 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; 151 bool onIsEqual(const GrFragmentProcessor&) const override; 152 GR_DECLARE_FRAGMENT_PROCESSOR_TEST 153 PMConversion fPmConversion; 154 typedef GrFragmentProcessor INHERITED; 155 }; 156 #endif 157 #endif 158