1/*
2 * Copyright 2016 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// This is a GPU-backend specific test.
9
10#include "Test.h"
11
12#if SK_SUPPORT_GPU
13#include "GrBackendSurface.h"
14#include "GrContextPriv.h"
15#include "GrProxyProvider.h"
16#include "GrRenderTarget.h"
17#include "GrRenderTargetProxy.h"
18#include "GrSurfaceProxy.h"
19#include "GrTexture.h"
20#include "GrTextureProxy.h"
21
22static sk_sp<GrSurfaceProxy> make_wrapped_FBO0(GrProxyProvider* provider,
23                                               skiatest::Reporter* reporter,
24                                               const GrSurfaceDesc& desc) {
25    GrGLFramebufferInfo fboInfo;
26    fboInfo.fFBOID = 0;
27    GrBackendRenderTarget backendRT(desc.fWidth, desc.fHeight, desc.fSampleCnt, 8,
28                                    desc.fConfig, fboInfo);
29
30    return provider->createWrappedRenderTargetProxy(backendRT, desc.fOrigin);
31}
32
33static sk_sp<GrSurfaceProxy> make_wrapped_offscreen_rt(GrProxyProvider* provider,
34                                                       const GrSurfaceDesc& desc) {
35    SkASSERT(kRenderTarget_GrSurfaceFlag == desc.fFlags);
36
37    return provider->createInstantiatedProxy(desc, SkBackingFit::kExact, SkBudgeted::kYes);
38}
39
40static sk_sp<GrSurfaceProxy> make_wrapped_texture(GrProxyProvider* provider,
41                                                  const GrSurfaceDesc& desc) {
42    return provider->createInstantiatedProxy(desc, SkBackingFit::kExact, SkBudgeted::kYes);
43}
44
45// Test converting between RenderTargetProxies and TextureProxies for wrapped
46// Proxies
47DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyConversionTest, reporter, ctxInfo) {
48    GrProxyProvider* proxyProvider = ctxInfo.grContext()->contextPriv().proxyProvider();
49
50    GrSurfaceDesc desc;
51    desc.fFlags = kRenderTarget_GrSurfaceFlag;
52    desc.fWidth = 64;
53    desc.fHeight = 64;
54    desc.fConfig = kRGBA_8888_GrPixelConfig;
55    desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
56
57    if (kOpenGL_GrBackend == ctxInfo.backend()) {
58        // External on-screen render target.
59        sk_sp<GrSurfaceProxy> sProxy(make_wrapped_FBO0(proxyProvider, reporter, desc));
60        if (sProxy) {
61            // RenderTarget-only
62            GrRenderTargetProxy* rtProxy = sProxy->asRenderTargetProxy();
63            REPORTER_ASSERT(reporter, rtProxy);
64            REPORTER_ASSERT(reporter, !rtProxy->asTextureProxy());
65            REPORTER_ASSERT(reporter, rtProxy->asRenderTargetProxy() == rtProxy);
66        }
67    }
68
69    {
70        // Internal offscreen render target.
71        sk_sp<GrSurfaceProxy> sProxy(make_wrapped_offscreen_rt(proxyProvider, desc));
72        if (sProxy) {
73            // Both RenderTarget and Texture
74            GrRenderTargetProxy* rtProxy = sProxy->asRenderTargetProxy();
75            REPORTER_ASSERT(reporter, rtProxy);
76            GrTextureProxy* tProxy = rtProxy->asTextureProxy();
77            REPORTER_ASSERT(reporter, tProxy);
78            REPORTER_ASSERT(reporter, tProxy->asRenderTargetProxy() == rtProxy);
79            REPORTER_ASSERT(reporter, rtProxy->asRenderTargetProxy() == rtProxy);
80        }
81    }
82
83    {
84        // Internal offscreen render target - but through GrTextureProxy
85        sk_sp<GrSurfaceProxy> sProxy(make_wrapped_texture(proxyProvider, desc));
86        if (sProxy) {
87            // Both RenderTarget and Texture
88            GrTextureProxy* tProxy = sProxy->asTextureProxy();
89            REPORTER_ASSERT(reporter, tProxy);
90            GrRenderTargetProxy* rtProxy = tProxy->asRenderTargetProxy();
91            REPORTER_ASSERT(reporter, rtProxy);
92            REPORTER_ASSERT(reporter, rtProxy->asTextureProxy() == tProxy);
93            REPORTER_ASSERT(reporter, tProxy->asTextureProxy() == tProxy);
94        }
95    }
96
97    {
98        desc.fFlags = kNone_GrSurfaceFlags; // force no-RT
99
100        sk_sp<GrSurfaceProxy> sProxy(make_wrapped_texture(proxyProvider, desc));
101        if (sProxy) {
102            // Texture-only
103            GrTextureProxy* tProxy = sProxy->asTextureProxy();
104            REPORTER_ASSERT(reporter, tProxy);
105            REPORTER_ASSERT(reporter, tProxy->asTextureProxy() == tProxy);
106            REPORTER_ASSERT(reporter, !tProxy->asRenderTargetProxy());
107        }
108    }
109}
110
111// Test converting between RenderTargetProxies and TextureProxies for deferred
112// Proxies
113DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DefferredProxyConversionTest, reporter, ctxInfo) {
114    GrProxyProvider* proxyProvider = ctxInfo.grContext()->contextPriv().proxyProvider();
115
116    GrSurfaceDesc desc;
117    desc.fFlags = kRenderTarget_GrSurfaceFlag;
118    desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
119    desc.fWidth = 64;
120    desc.fHeight = 64;
121    desc.fConfig = kRGBA_8888_GrPixelConfig;
122
123    {
124        sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(desc, SkBackingFit::kApprox,
125                                                                 SkBudgeted::kYes);
126
127        // Both RenderTarget and Texture
128        GrRenderTargetProxy* rtProxy = proxy->asRenderTargetProxy();
129        REPORTER_ASSERT(reporter, rtProxy);
130        GrTextureProxy* tProxy = rtProxy->asTextureProxy();
131        REPORTER_ASSERT(reporter, tProxy);
132        REPORTER_ASSERT(reporter, tProxy->asRenderTargetProxy() == rtProxy);
133        REPORTER_ASSERT(reporter, rtProxy->asRenderTargetProxy() == rtProxy);
134    }
135
136    {
137        sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(desc, SkBackingFit::kApprox,
138                                                                 SkBudgeted::kYes);
139
140        // Both RenderTarget and Texture - but via GrTextureProxy
141        GrTextureProxy* tProxy = proxy->asTextureProxy();
142        REPORTER_ASSERT(reporter, tProxy);
143        GrRenderTargetProxy* rtProxy = tProxy->asRenderTargetProxy();
144        REPORTER_ASSERT(reporter, rtProxy);
145        REPORTER_ASSERT(reporter, rtProxy->asTextureProxy() == tProxy);
146        REPORTER_ASSERT(reporter, tProxy->asTextureProxy() == tProxy);
147    }
148
149    {
150        desc.fFlags = kNone_GrSurfaceFlags; // force no-RT
151        desc.fOrigin = kTopLeft_GrSurfaceOrigin;
152
153        sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(desc, SkBackingFit::kApprox,
154                                                                 SkBudgeted::kYes);
155        // Texture-only
156        GrTextureProxy* tProxy = proxy->asTextureProxy();
157        REPORTER_ASSERT(reporter, tProxy);
158        REPORTER_ASSERT(reporter, tProxy->asTextureProxy() == tProxy);
159        REPORTER_ASSERT(reporter, !tProxy->asRenderTargetProxy());
160    }
161}
162#endif
163