1 /* 2 * Copyright 2017 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 #include "gm.h" 9 #include "sk_tool_utils.h" 10 #include "SkRandom.h" 11 12 #if SK_SUPPORT_GPU 13 #include "etc1.h" 14 15 #include "GrContext.h" 16 #include "GrRenderTargetContext.h" 17 #include "GrRenderTargetContextPriv.h" 18 #include "GrTextureProxy.h" 19 #include "effects/GrSimpleTextureEffect.h" 20 #include "ops/GrRectOpFactory.h" 21 22 // Basic test of Ganesh's ETC1 support 23 class ETC1GM : public skiagm::GM { 24 public: ETC1GM()25 ETC1GM() { 26 this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC)); 27 } 28 29 protected: onShortName()30 SkString onShortName() override { 31 return SkString("etc1"); 32 } 33 onISize()34 SkISize onISize() override { 35 return SkISize::Make(kTexWidth + 2*kPad, kTexHeight + 2*kPad); 36 } 37 38 // TODO: we should be creating an ETC1 SkData blob here and going through SkImageCacherator. 39 // That will require an ETC1 Codec though - so for later. onOnceBeforeDraw()40 void onOnceBeforeDraw() override { 41 SkBitmap bm; 42 SkImageInfo ii = SkImageInfo::Make(kTexWidth, kTexHeight, kRGB_565_SkColorType, 43 kOpaque_SkAlphaType); 44 bm.allocPixels(ii); 45 46 bm.erase(SK_ColorBLUE, SkIRect::MakeWH(kTexWidth, kTexHeight)); 47 48 for (int y = 0; y < kTexHeight; y += 4) { 49 for (int x = 0; x < kTexWidth; x += 4) { 50 bm.erase((x+y) % 8 ? SK_ColorRED : SK_ColorGREEN, SkIRect::MakeXYWH(x, y, 4, 4)); 51 } 52 } 53 54 int size = etc1_get_encoded_data_size(bm.width(), bm.height()); 55 fETC1Data.reset(size); 56 57 unsigned char* pixels = (unsigned char*) fETC1Data.get(); 58 59 if (etc1_encode_image((unsigned char*) bm.getAddr16(0, 0), 60 bm.width(), bm.height(), 2, bm.rowBytes(), pixels)) { 61 fETC1Data.reset(); 62 } 63 } 64 onDraw(SkCanvas * canvas)65 void onDraw(SkCanvas* canvas) override { 66 GrRenderTargetContext* renderTargetContext = 67 canvas->internal_private_accessTopLayerRenderTargetContext(); 68 if (!renderTargetContext) { 69 skiagm::GM::DrawGpuOnlyMessage(canvas); 70 return; 71 } 72 73 GrContext* context = canvas->getGrContext(); 74 if (!context) { 75 return; 76 } 77 78 GrSurfaceDesc desc; 79 desc.fConfig = kETC1_GrPixelConfig; 80 desc.fWidth = kTexWidth; 81 desc.fHeight = kTexHeight; 82 83 sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeDeferred(context->resourceProvider(), 84 desc, SkBudgeted::kYes, 85 fETC1Data.get(), 0); 86 if (!proxy) { 87 return; 88 } 89 90 const SkMatrix trans = SkMatrix::MakeTrans(-kPad, -kPad); 91 92 sk_sp<GrFragmentProcessor> fp = GrSimpleTextureEffect::Make(context->resourceProvider(), 93 std::move(proxy), 94 nullptr, trans); 95 96 GrPaint grPaint; 97 grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc)); 98 grPaint.addColorFragmentProcessor(std::move(fp)); 99 100 SkRect rect = SkRect::MakeXYWH(kPad, kPad, kTexWidth, kTexHeight); 101 102 std::unique_ptr<GrMeshDrawOp> op(GrRectOpFactory::MakeNonAAFill( 103 GrColor_WHITE, SkMatrix::I(), rect, nullptr, nullptr)); 104 renderTargetContext->priv().testingOnly_addMeshDrawOp(std::move(grPaint), GrAAType::kNone, 105 std::move(op)); 106 } 107 108 private: 109 static const int kPad = 8; 110 static const int kTexWidth = 16; 111 static const int kTexHeight = 20; 112 113 SkAutoTMalloc<char> fETC1Data; 114 115 typedef GM INHERITED; 116 }; 117 118 ////////////////////////////////////////////////////////////////////////////// 119 120 DEF_GM(return new ETC1GM;) 121 122 #endif 123