1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2017 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkTypes.h"
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if SK_SUPPORT_GPU
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrBackendSurface.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrGpu.h"
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkCanvas.h"
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkDeferredDisplayListRecorder.h"
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGpuDevice.h"
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkSurface.h"
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkSurface_Gpu.h"
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkSurfaceCharacterization.h"
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkSurfaceProps.h"
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "Test.h"
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SurfaceParameters {
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const int kNumParams = 8;
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const int kSampleCount = 5;
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SurfaceParameters()
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            : fWidth(64)
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            , fHeight(64)
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            , fOrigin(kTopLeft_GrSurfaceOrigin)
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            , fColorType(kRGBA_8888_SkColorType)
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            , fColorSpace(SkColorSpace::MakeSRGB())
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            , fSampleCount(1)
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            , fSurfaceProps(0x0, kUnknown_SkPixelGeometry) {}
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int sampleCount() const { return fSampleCount; }
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Modify the SurfaceParameters in just one way
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void modify(int i) {
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        switch (i) {
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        case 0:
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fWidth = 63;
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            break;
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        case 1:
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fHeight = 63;
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            break;
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        case 2:
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fOrigin = kBottomLeft_GrSurfaceOrigin;
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            break;
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        case 3:
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fColorType = kRGBA_F16_SkColorType;
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            break;
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        case 4:
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fColorSpace = SkColorSpace::MakeSRGBLinear();
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            break;
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        case kSampleCount:
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fSampleCount = 4;
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            break;
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        case 6:
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fSurfaceProps = SkSurfaceProps(0x0, kRGB_H_SkPixelGeometry);
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            break;
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        case 7:
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fSurfaceProps = SkSurfaceProps(SkSurfaceProps::kUseDeviceIndependentFonts_Flag,
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                           kUnknown_SkPixelGeometry);
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            break;
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Create the surface with the current set of parameters
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<SkSurface> make(GrContext* context) const {
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // Note that Ganesh doesn't make use of the SkImageInfo's alphaType
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkImageInfo ii = SkImageInfo::Make(fWidth, fHeight, fColorType,
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                           kPremul_SkAlphaType, fColorSpace);
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, ii, fSampleCount,
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                           fOrigin, &fSurfaceProps);
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int                 fWidth;
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int                 fHeight;
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrSurfaceOrigin     fOrigin;
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkColorType         fColorType;
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<SkColorSpace> fColorSpace;
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int                 fSampleCount;
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkSurfaceProps      fSurfaceProps;
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// This tests SkSurfaceCharacterization/SkSurface compatibility
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GPUTEST_FOR_ALL_CONTEXTS(SkSurfaceCharacterization, reporter, ctxInfo) {
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = ctxInfo.grContext();
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Create a bitmap that we can readback into
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType,
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                              kPremul_SkAlphaType);
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkBitmap bitmap;
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bitmap.allocPixels(imageInfo);
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    std::unique_ptr<SkDeferredDisplayList> ddl;
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // First, create a DDL using the stock SkSurface parameters
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    {
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SurfaceParameters params;
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<SkSurface> s = params.make(context);
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!s) {
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return;
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkSurfaceCharacterization c;
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkAssertResult(s->characterize(&c));
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkDeferredDisplayListRecorder r(c);
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkCanvas* canvas = r.getCanvas();
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!canvas) {
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return;
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawRect(SkRect::MakeXYWH(10, 10, 10, 10), SkPaint());
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ddl = r.detach();
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, s->draw(ddl.get()));
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Then, alter each parameter in turn and check that the DDL & surface are incompatible
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SurfaceParameters params;
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        params.modify(i);
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<SkSurface> s = params.make(context);
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!s) {
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            continue;
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (SurfaceParameters::kSampleCount == i) {
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkSurface_Gpu* gpuSurf = static_cast<SkSurface_Gpu*>(s.get());
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            int supportedSampleCount = context->caps()->getSampleCount(
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                params.sampleCount(),
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                gpuSurf->getDevice()->accessRenderTargetContext()->asRenderTargetProxy()->config());
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (1 == supportedSampleCount) {
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                // If changing the sample count won't result in a different
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                // surface characterization, skip this step
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, !s->draw(ddl.get()));
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Next test the compatibility of resource cache parameters
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    {
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const SurfaceParameters params;
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<SkSurface> s = params.make(context);
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int maxResourceCount;
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t maxResourceBytes;
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        context->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        context->setResourceCacheLimits(maxResourceCount/2, maxResourceBytes);
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, !s->draw(ddl.get()));
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        context->setResourceCacheLimits(maxResourceCount, maxResourceBytes/2);
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, !s->draw(ddl.get()));
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // DDL TODO: once proxies/ops can be de-instantiated we can re-enable these tests.
169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // For now, DDLs are drawn once.
170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if 0
171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // resource limits >= those at characterization time are accepted
172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        context->setResourceCacheLimits(2*maxResourceCount, maxResourceBytes);
173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, s->draw(ddl.get()));
174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        context->setResourceCacheLimits(maxResourceCount, 2*maxResourceBytes);
177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, s->draw(ddl.get()));
178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        context->setResourceCacheLimits(maxResourceCount, maxResourceBytes);
181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, s->draw(ddl.get()));
182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Make sure non-GPU-backed surfaces fail characterization
187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    {
188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkImageInfo ii = SkImageInfo::MakeN32(64, 64, kOpaque_SkAlphaType);
189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<SkSurface> rasterSurface = SkSurface::MakeRaster(ii);
191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkSurfaceCharacterization c;
192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, !rasterSurface->characterize(&c));
193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic constexpr int kSize = 8;
197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstruct TextureReleaseChecker {
199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TextureReleaseChecker() : fReleaseCount(0) {}
200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fReleaseCount;
201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static void Release(void* self) {
202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        static_cast<TextureReleaseChecker*>(self)->fReleaseCount++;
203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotenum class DDLStage { kMakeImage, kDrawImage, kDetach, kDrawDDL };
207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// This tests the ability to create and use wrapped textures in a DDL world
209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLWrapBackendTest, reporter, ctxInfo) {
210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = ctxInfo.grContext();
211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpu* gpu = context->contextPriv().getGpu();
212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (auto lastStage : { DDLStage::kMakeImage, DDLStage::kDrawImage,
213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            DDLStage::kDetach, DDLStage::kDrawDDL } ) {
214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (auto earlyImageReset : { false , true } ) {
215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    nullptr, kSize, kSize, kRGBA_8888_GrPixelConfig, false, GrMipMapped::kNo);
217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (!backendTex.isValid()) {
218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SurfaceParameters params;
222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            sk_sp<SkSurface> s = params.make(context);
224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (!s) {
225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                gpu->deleteTestingOnlyBackendTexture(&backendTex);
226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkSurfaceCharacterization c;
230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkAssertResult(s->characterize(&c));
231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            std::unique_ptr<SkDeferredDisplayListRecorder> recorder(
233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    new SkDeferredDisplayListRecorder(c));
234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkCanvas* canvas = recorder->getCanvas();
236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (!canvas) {
237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                gpu->deleteTestingOnlyBackendTexture(&backendTex);
238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            GrContext* deferredContext = canvas->getGrContext();
242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (!deferredContext) {
243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                gpu->deleteTestingOnlyBackendTexture(&backendTex);
244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            sk_sp<SkImage> image = SkImage::MakeFromAdoptedTexture(deferredContext, backendTex,
248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                                   kTopLeft_GrSurfaceOrigin,
249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                                   kRGBA_8888_SkColorType,
250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                                   kPremul_SkAlphaType, nullptr);
251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // Adopted Textures are not supported in DDL
252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, !image);
253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            TextureReleaseChecker releaseChecker;
255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            image = SkImage::MakeFromTexture(deferredContext, backendTex,
256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                             kTopLeft_GrSurfaceOrigin,
257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                             kRGBA_8888_SkColorType,
258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                             kPremul_SkAlphaType, nullptr,
259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                             TextureReleaseChecker::Release, &releaseChecker);
260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, image);
262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (!image) {
263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                gpu->deleteTestingOnlyBackendTexture(&backendTex);
264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (DDLStage::kMakeImage == lastStage) {
268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                image.reset();
270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 1 == releaseChecker.fReleaseCount);
271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                recorder.reset();
272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 1 == releaseChecker.fReleaseCount);
273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                gpu->deleteTestingOnlyBackendTexture(&backendTex);
274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->drawImage(image.get(), 0, 0);
278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (earlyImageReset) {
280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                image.reset();
282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                // Ref should still be held by DDL recorder since we did the draw
283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (DDLStage::kDrawImage == lastStage) {
287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                recorder.reset();
289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (earlyImageReset) {
290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    REPORTER_ASSERT(reporter, 1 == releaseChecker.fReleaseCount);
291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } else {
292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    image.reset();
294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    REPORTER_ASSERT(reporter, 1 == releaseChecker.fReleaseCount);
295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                gpu->deleteTestingOnlyBackendTexture(&backendTex);
297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            std::unique_ptr<SkDeferredDisplayList> ddl = recorder->detach();
301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (DDLStage::kDetach == lastStage) {
302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                recorder.reset();
304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef SK_RASTER_RECORDER_IMPLEMENTATION
305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                ddl.reset();
308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (earlyImageReset) {
309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    REPORTER_ASSERT(reporter, 1 == releaseChecker.fReleaseCount);
310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } else {
311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    image.reset();
313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    REPORTER_ASSERT(reporter, 1 == releaseChecker.fReleaseCount);
314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                gpu->deleteTestingOnlyBackendTexture(&backendTex);
316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                continue;
317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, s->draw(ddl.get()));
320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            recorder.reset();
323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef SK_RASTER_RECORDER_IMPLEMENTATION
324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            ddl.reset();
327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef SK_RASTER_RECORDER_IMPLEMENTATION
328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // Force all draws to flush and sync by calling a read pixels
332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkImageInfo imageInfo = SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType,
333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                      kPremul_SkAlphaType);
334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkBitmap bitmap;
335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            bitmap.allocPixels(imageInfo);
336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (earlyImageReset) {
339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 1 == releaseChecker.fReleaseCount);
340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            } else {
341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                image.reset();
343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 1 == releaseChecker.fReleaseCount);
344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            gpu->deleteTestingOnlyBackendTexture(&backendTex);
347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
353