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