1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 7cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com 8cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com// This test only works with the GPU backend. 9cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com 10d9f826c0dbc38f3608797a02948adf9bc99d5d50bsalomon@google.com#include "gm.h" 11a68937c950847cea2eb7064ef5b63feb82ed3a71bsalomon@google.com 12a68937c950847cea2eb7064ef5b63feb82ed3a71bsalomon@google.com#if SK_SUPPORT_GPU 13d9f826c0dbc38f3608797a02948adf9bc99d5d50bsalomon@google.com#include "GrContext.h" 14901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips#include "GrContextPriv.h" 150bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips#include "GrProxyProvider.h" 161105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman#include "GrRenderTargetContext.h" 17901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips#include "GrTextureContext.h" 1802fa32c6d1ef4b7b05aa06df8be4add42a1712d3csmartdalton#include "GrFixedClip.h" 198d95ffa497091d0c9c7cda099684c7bca6714a17egdaniel#include "SkColorPriv.h" 2040fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips#include "SkGr.h" 219513143efa734bef0c1a0c7f945022572dbc8518egdaniel#include "effects/GrPorterDuffXferProcessor.h" 229513143efa734bef0c1a0c7f945022572dbc8518egdaniel#include "effects/GrSimpleTextureEffect.h" 23d9f826c0dbc38f3608797a02948adf9bc99d5d50bsalomon@google.com 24dbfd7ab10883f173f5c1b653a233e18dc6142002mtkleinconstexpr int S = 200; 25901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillipsconstexpr int kStride = 2 * S; 26901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips 27901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips// Fill in the pixels: 28901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips// gray | white 29901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips// ------------- 30901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips// black | gray 31901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillipsstatic void fill_in_pixels(SkPMColor* pixels) { 32901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips const SkPMColor gray = SkPackARGB32(0x40, 0x40, 0x40, 0x40); 33901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips const SkPMColor white = SkPackARGB32(0xff, 0xff, 0xff, 0xff); 34901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips const SkPMColor black = SkPackARGB32(0x00, 0x00, 0x00, 0x00); 35901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips 36901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips int offset = 0; 37901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips 38901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips // fill upper-left 39901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips for (int y = 0; y < S; ++y) { 40901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips for (int x = 0; x < S; ++x) { 41901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips pixels[offset + y * kStride + x] = gray; 42901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips } 43901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips } 44901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips // fill upper-right 45901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips offset = S; 46901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips for (int y = 0; y < S; ++y) { 47901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips for (int x = 0; x < S; ++x) { 48901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips pixels[offset + y * kStride + x] = white; 49901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips } 50901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips } 51901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips // fill lower left 52901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips offset = S * kStride; 53901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips for (int y = 0; y < S; ++y) { 54901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips for (int x = 0; x < S; ++x) { 55901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips pixels[offset + y * kStride + x] = black; 56901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips } 57901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips } 58901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips // fill lower right 59901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips offset = S * kStride + S; 60901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips for (int y = 0; y < S; ++y) { 61901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips for (int x = 0; x < S; ++x) { 62901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips pixels[offset + y * kStride + x] = gray; 63901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips } 64901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips } 65901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips} 66d9f826c0dbc38f3608797a02948adf9bc99d5d50bsalomon@google.com 672a24338c777462e04a2b26295f9c034155ee8f3ehalcanaryDEF_SIMPLE_GM_BG(texdata, canvas, 2 * S, 2 * S, SK_ColorBLACK) { 681105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman GrRenderTargetContext* renderTargetContext = 691105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman canvas->internal_private_accessTopLayerRenderTargetContext(); 701105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman if (!renderTargetContext) { 71175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips skiagm::GM::DrawGpuOnlyMessage(canvas); 72175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips return; 73175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips } 74d9f826c0dbc38f3608797a02948adf9bc99d5d50bsalomon@google.com 75175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips GrContext* context = canvas->getGrContext(); 76175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips if (!context) { 77175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips return; 78175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips } 79d9f826c0dbc38f3608797a02948adf9bc99d5d50bsalomon@google.com 800bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider(); 81901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips const SkImageInfo ii = SkImageInfo::Make(S, S, kBGRA_8888_SkColorType, kPremul_SkAlphaType); 82901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips 83175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips SkAutoTArray<SkPMColor> gTextureData((2 * S) * (2 * S)); 84dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein const SkPMColor red = SkPackARGB32(0x80, 0x80, 0x00, 0x00); 85dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein const SkPMColor blue = SkPackARGB32(0x80, 0x00, 0x00, 0x80); 86dbfd7ab10883f173f5c1b653a233e18dc6142002mtklein const SkPMColor green = SkPackARGB32(0x80, 0x00, 0x80, 0x00); 87175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips for (int i = 0; i < 2; ++i) { 88901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips fill_in_pixels(gTextureData.get()); 89d9f826c0dbc38f3608797a02948adf9bc99d5d50bsalomon@google.com 90175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips GrSurfaceDesc desc; 91677da9d4af2558ddd50a900e90a093d1b522bd5frobertphillips desc.fOrigin = i ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin; 92175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips desc.fWidth = 2 * S; 93175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips desc.fHeight = 2 * S; 9440fd7c94c24bb30d888c3d85a79cbb96c7fbf800Robert Phillips desc.fConfig = SkImageInfo2GrPixelConfig(ii, *context->caps()); 950a7aa14bf36cbb444b84902a37591d7a9c84fbd0Greg Daniel SkASSERT(kUnknown_GrPixelConfig != desc.fConfig); 963e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com 970bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(desc, SkBudgeted::kNo, 980bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips gTextureData.get(), 0); 99901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips if (!proxy) { 100901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips return; 101901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips } 102901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips 103901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips sk_sp<GrSurfaceContext> tContext = context->contextPriv().makeWrappedSurfaceContext( 104d5f9cdd4b3a6ab0e49bb1a56f2e52e2f40edd0faRobert Phillips std::move(proxy)); 105901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips 106901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips if (!tContext) { 107175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips return; 108175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips } 1099513143efa734bef0c1a0c7f945022572dbc8518egdaniel 110175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips // setup new clip 111846c051a4800b3cea341a0195db24297d6d9047fcdalton GrFixedClip clip(SkIRect::MakeWH(2*S, 2*S)); 112d9f826c0dbc38f3608797a02948adf9bc99d5d50bsalomon@google.com 113175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips GrPaint paint; 1147d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed paint.setPorterDuffXPFactory(SkBlendMode::kSrcOver); 115d9f826c0dbc38f3608797a02948adf9bc99d5d50bsalomon@google.com 116175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips SkMatrix vm; 117175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips if (i) { 118901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips vm.setRotate(90 * SK_Scalar1, S * SK_Scalar1, S * SK_Scalar1); 119b62da80cbf6643c1944d3ebf8df233f286bd3fdebsalomon } else { 120175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips vm.reset(); 121d9f826c0dbc38f3608797a02948adf9bc99d5d50bsalomon@google.com } 1222240be96d97b5ac0886381d74a21f1e2a0928f55Brian Osman paint.addColorTextureProcessor(tContext->asTextureProxyRef(), vm); 123175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips 124b74ef035a42af8acf028abd129cb59862cb15c46Brian Salomon renderTargetContext->drawRect(clip, GrPaint::Clone(paint), GrAA::kNo, vm, 12582f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon SkRect::MakeWH(2 * S, 2 * S)); 126175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips 127175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips // now update the lower right of the texture in first pass 128175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips // or upper right in second pass 129175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips for (int y = 0; y < S; ++y) { 130175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips for (int x = 0; x < S; ++x) { 131901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips gTextureData[y * kStride + x] = ((x + y) % 2) ? (i ? green : red) : blue; 132175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips } 133175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips } 134901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips 135901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips if (!tContext->writePixels(ii, gTextureData.get(), 4 * kStride, S, i ? 0 : S)) { 136901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips continue; 137901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips } 138901f29ad3e38b7072a2abef5ff1665cd755d21a2Robert Phillips 13982f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon renderTargetContext->drawRect(clip, std::move(paint), GrAA::kNo, vm, 14082f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon SkRect::MakeWH(2 * S, 2 * S)); 141175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips } 142d9f826c0dbc38f3608797a02948adf9bc99d5d50bsalomon@google.com} 143cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif 144175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips 145