|  | /* | 
|  | * Copyright 2011 Google Inc. | 
|  | * | 
|  | * Use of this source code is governed by a BSD-style license that can be | 
|  | * found in the LICENSE file. | 
|  | */ | 
|  |  | 
|  | // This test only works with the GPU backend. | 
|  |  | 
|  | #include "gm.h" | 
|  |  | 
|  | #if SK_SUPPORT_GPU | 
|  | #include "GrContext.h" | 
|  | #include "GrContextPriv.h" | 
|  | #include "GrProxyProvider.h" | 
|  | #include "GrRenderTargetContext.h" | 
|  | #include "GrTextureContext.h" | 
|  | #include "GrFixedClip.h" | 
|  | #include "SkColorPriv.h" | 
|  | #include "SkGr.h" | 
|  | #include "effects/GrPorterDuffXferProcessor.h" | 
|  | #include "effects/GrSimpleTextureEffect.h" | 
|  |  | 
|  | constexpr int S = 200; | 
|  | constexpr int kStride = 2 * S; | 
|  |  | 
|  | // Fill in the pixels: | 
|  | //   gray  | white | 
|  | //   ------------- | 
|  | //   black | gray | 
|  | static void fill_in_pixels(SkPMColor* pixels) { | 
|  | const SkPMColor gray  = SkPackARGB32(0x40, 0x40, 0x40, 0x40); | 
|  | const SkPMColor white = SkPackARGB32(0xff, 0xff, 0xff, 0xff); | 
|  | const SkPMColor black = SkPackARGB32(0x00, 0x00, 0x00, 0x00); | 
|  |  | 
|  | int offset = 0; | 
|  |  | 
|  | // fill upper-left | 
|  | for (int y = 0; y < S; ++y) { | 
|  | for (int x = 0; x < S; ++x) { | 
|  | pixels[offset + y * kStride + x] = gray; | 
|  | } | 
|  | } | 
|  | // fill upper-right | 
|  | offset = S; | 
|  | for (int y = 0; y < S; ++y) { | 
|  | for (int x = 0; x < S; ++x) { | 
|  | pixels[offset + y * kStride + x] = white; | 
|  | } | 
|  | } | 
|  | // fill lower left | 
|  | offset = S * kStride; | 
|  | for (int y = 0; y < S; ++y) { | 
|  | for (int x = 0; x < S; ++x) { | 
|  | pixels[offset + y * kStride + x] = black; | 
|  | } | 
|  | } | 
|  | // fill lower right | 
|  | offset = S * kStride + S; | 
|  | for (int y = 0; y < S; ++y) { | 
|  | for (int x = 0; x < S; ++x) { | 
|  | pixels[offset + y * kStride + x] = gray; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | DEF_SIMPLE_GM_BG(texdata, canvas, 2 * S, 2 * S, SK_ColorBLACK) { | 
|  | GrRenderTargetContext* renderTargetContext = | 
|  | canvas->internal_private_accessTopLayerRenderTargetContext(); | 
|  | if (!renderTargetContext) { | 
|  | skiagm::GM::DrawGpuOnlyMessage(canvas); | 
|  | return; | 
|  | } | 
|  |  | 
|  | GrContext* context = canvas->getGrContext(); | 
|  | if (!context) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider(); | 
|  | const SkImageInfo ii = SkImageInfo::Make(S, S, kBGRA_8888_SkColorType, kPremul_SkAlphaType); | 
|  |  | 
|  | SkAutoTArray<SkPMColor> gTextureData((2 * S) * (2 * S)); | 
|  | const SkPMColor red   = SkPackARGB32(0x80, 0x80, 0x00, 0x00); | 
|  | const SkPMColor blue  = SkPackARGB32(0x80, 0x00, 0x00, 0x80); | 
|  | const SkPMColor green = SkPackARGB32(0x80, 0x00, 0x80, 0x00); | 
|  | for (int i = 0; i < 2; ++i) { | 
|  | fill_in_pixels(gTextureData.get()); | 
|  |  | 
|  | GrSurfaceDesc desc; | 
|  | desc.fOrigin    = i ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin; | 
|  | desc.fWidth     = 2 * S; | 
|  | desc.fHeight    = 2 * S; | 
|  | desc.fConfig    = SkImageInfo2GrPixelConfig(ii, *context->caps()); | 
|  |  | 
|  | sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(desc, SkBudgeted::kNo, | 
|  | gTextureData.get(), 0); | 
|  | if (!proxy) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | sk_sp<GrSurfaceContext> tContext = context->contextPriv().makeWrappedSurfaceContext( | 
|  | std::move(proxy), nullptr); | 
|  |  | 
|  | if (!tContext) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | // setup new clip | 
|  | GrFixedClip clip(SkIRect::MakeWH(2*S, 2*S)); | 
|  |  | 
|  | GrPaint paint; | 
|  | paint.setPorterDuffXPFactory(SkBlendMode::kSrcOver); | 
|  |  | 
|  | SkMatrix vm; | 
|  | if (i) { | 
|  | vm.setRotate(90 * SK_Scalar1, S * SK_Scalar1, S * SK_Scalar1); | 
|  | } else { | 
|  | vm.reset(); | 
|  | } | 
|  | paint.addColorTextureProcessor(tContext->asTextureProxyRef(), vm); | 
|  |  | 
|  | renderTargetContext->drawRect(clip, GrPaint::Clone(paint), GrAA::kNo, vm, | 
|  | SkRect::MakeWH(2 * S, 2 * S)); | 
|  |  | 
|  | // now update the lower right of the texture in first pass | 
|  | // or upper right in second pass | 
|  | for (int y = 0; y < S; ++y) { | 
|  | for (int x = 0; x < S; ++x) { | 
|  | gTextureData[y * kStride + x] = ((x + y) % 2) ? (i ? green : red) : blue; | 
|  | } | 
|  | } | 
|  |  | 
|  | if (!tContext->writePixels(ii, gTextureData.get(), 4 * kStride, S, i ? 0 : S)) { | 
|  | continue; | 
|  | } | 
|  |  | 
|  | renderTargetContext->drawRect(clip, std::move(paint), GrAA::kNo, vm, | 
|  | SkRect::MakeWH(2 * S, 2 * S)); | 
|  | } | 
|  | } | 
|  | #endif | 
|  |  |