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