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 "include/core/SkTypes.h" 14 15 #include "include/gpu/GrContext.h" 16 #include "src/gpu/GrClip.h" 17 #include "src/gpu/GrContextPriv.h" 18 #include "src/gpu/GrProxyProvider.h" 19 #include "src/gpu/GrRenderTargetContext.h" 20 21 #include "src/gpu/GrCoordTransform.h" 22 #include "src/gpu/GrFragmentProcessor.h" 23 class GrConfigConversionEffect : public GrFragmentProcessor { 24 public: TestForPreservingPMConversions(GrContext * context)25 static bool TestForPreservingPMConversions(GrContext* context) { 26 static constexpr int kSize = 256; 27 static constexpr GrColorType kColorType = GrColorType::kRGBA_8888; 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 memset(firstRead, 0, kSize * kSize * sizeof(uint32_t)); 46 memset(secondRead, 0, kSize * kSize * sizeof(uint32_t)); 47 48 const SkImageInfo ii = 49 SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType); 50 51 sk_sp<GrRenderTargetContext> readRTC(context->priv().makeDeferredRenderTargetContext( 52 SkBackingFit::kExact, kSize, kSize, kColorType, nullptr)); 53 sk_sp<GrRenderTargetContext> tempRTC(context->priv().makeDeferredRenderTargetContext( 54 SkBackingFit::kExact, kSize, kSize, kColorType, nullptr)); 55 if (!readRTC || !readRTC->asTextureProxy() || !tempRTC) { 56 return false; 57 } 58 // Adding discard to appease vulkan validation warning about loading uninitialized data on 59 // draw 60 readRTC->discard(); 61 62 GrProxyProvider* proxyProvider = context->priv().proxyProvider(); 63 64 SkPixmap pixmap(ii, srcData, 4 * kSize); 65 66 // This function is only ever called if we are in a GrContext that has a GrGpu since we are 67 // calling read pixels here. Thus the pixel data will be uploaded immediately and we don't 68 // need to keep the pixel data alive in the proxy. Therefore the ReleaseProc is nullptr. 69 sk_sp<SkImage> image = SkImage::MakeFromRaster(pixmap, nullptr, nullptr); 70 71 sk_sp<GrTextureProxy> dataProxy = proxyProvider->createTextureProxy( 72 std::move(image), 1, SkBudgeted::kYes, SkBackingFit::kExact); 73 if (!dataProxy) { 74 return false; 75 } 76 77 static const SkRect kRect = SkRect::MakeIWH(kSize, kSize); 78 79 // We do a PM->UPM draw from dataTex to readTex and read the data. Then we do a UPM->PM draw 80 // from readTex to tempTex followed by a PM->UPM draw to readTex and finally read the data. 81 // We then verify that two reads produced the same values. 82 83 GrPaint paint1; 84 GrPaint paint2; 85 GrPaint paint3; 86 std::unique_ptr<GrFragmentProcessor> pmToUPM( 87 new GrConfigConversionEffect(PMConversion::kToUnpremul)); 88 std::unique_ptr<GrFragmentProcessor> upmToPM( 89 new GrConfigConversionEffect(PMConversion::kToPremul)); 90 91 paint1.addColorTextureProcessor(dataProxy, SkMatrix::I()); 92 paint1.addColorFragmentProcessor(pmToUPM->clone()); 93 paint1.setPorterDuffXPFactory(SkBlendMode::kSrc); 94 95 readRTC->fillRectToRect(GrNoClip(), std::move(paint1), GrAA::kNo, SkMatrix::I(), kRect, 96 kRect); 97 if (!readRTC->readPixels(ii, firstRead, 0, {0, 0})) { 98 return false; 99 } 100 101 // Adding discard to appease vulkan validation warning about loading uninitialized data on 102 // draw 103 tempRTC->discard(); 104 105 paint2.addColorTextureProcessor(readRTC->asTextureProxyRef(), SkMatrix::I()); 106 paint2.addColorFragmentProcessor(std::move(upmToPM)); 107 paint2.setPorterDuffXPFactory(SkBlendMode::kSrc); 108 109 tempRTC->fillRectToRect(GrNoClip(), std::move(paint2), GrAA::kNo, SkMatrix::I(), kRect, 110 kRect); 111 112 paint3.addColorTextureProcessor(tempRTC->asTextureProxyRef(), SkMatrix::I()); 113 paint3.addColorFragmentProcessor(std::move(pmToUPM)); 114 paint3.setPorterDuffXPFactory(SkBlendMode::kSrc); 115 116 readRTC->fillRectToRect(GrNoClip(), std::move(paint3), GrAA::kNo, SkMatrix::I(), kRect, 117 kRect); 118 119 if (!readRTC->readPixels(ii, secondRead, 0, {0, 0})) { 120 return false; 121 } 122 123 for (int y = 0; y < kSize; ++y) { 124 for (int x = 0; x <= y; ++x) { 125 if (firstRead[kSize * y + x] != secondRead[kSize * y + x]) { 126 return false; 127 } 128 } 129 } 130 131 return true; 132 } 133 Make(std::unique_ptr<GrFragmentProcessor> fp,PMConversion pmConversion)134 static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp, 135 PMConversion pmConversion) { 136 if (!fp) { 137 return nullptr; 138 } 139 std::unique_ptr<GrFragmentProcessor> ccFP(new GrConfigConversionEffect(pmConversion)); 140 std::unique_ptr<GrFragmentProcessor> fpPipeline[] = {std::move(fp), std::move(ccFP)}; 141 return GrFragmentProcessor::RunInSeries(fpPipeline, 2); 142 } 143 GrConfigConversionEffect(const GrConfigConversionEffect& src); 144 std::unique_ptr<GrFragmentProcessor> clone() const override; name()145 const char* name() const override { return "ConfigConversionEffect"; } 146 PMConversion pmConversion; 147 148 private: GrConfigConversionEffect(PMConversion pmConversion)149 GrConfigConversionEffect(PMConversion pmConversion) 150 : INHERITED(kGrConfigConversionEffect_ClassID, kNone_OptimizationFlags) 151 , pmConversion(pmConversion) {} 152 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; 153 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; 154 bool onIsEqual(const GrFragmentProcessor&) const override; 155 GR_DECLARE_FRAGMENT_PROCESSOR_TEST 156 typedef GrFragmentProcessor INHERITED; 157 }; 158 #endif 159