GrRenderTargetProxy.cpp revision f9635999a4aa8810d04e8ef04594a9fbcc061e3d
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#include "GrRenderTargetProxy.h"
9
10#include "GrCaps.h"
11#include "GrDrawTarget.h"
12#include "GrGpuResourcePriv.h"
13
14// Deferred version
15// TODO: we can probably munge the 'desc' in both the wrapped and deferred
16// cases to make the sampleConfig/numSamples stuff more rational.
17GrRenderTargetProxy::GrRenderTargetProxy(const GrCaps& caps, const GrSurfaceDesc& desc,
18                                         SkBackingFit fit, SkBudgeted budgeted)
19    : INHERITED(desc, fit, budgeted)
20    , fTarget(nullptr)
21    , fFlags(GrRenderTargetPriv::Flags::kNone)
22    , fLastDrawTarget(nullptr) {
23    // Since we know the newly created render target will be internal, we are able to precompute
24    // what the flags will ultimately end up being.
25    if (caps.usesMixedSamples() && fDesc.fSampleCnt > 0) {
26        fFlags |= GrRenderTargetPriv::Flags::kMixedSampled;
27    }
28    if (caps.maxWindowRectangles() > 0) {
29        fFlags |= GrRenderTargetPriv::Flags::kWindowRectsSupport;
30    }
31}
32
33// Wrapped version
34GrRenderTargetProxy::GrRenderTargetProxy(const GrCaps& caps, sk_sp<GrRenderTarget> rt)
35    : INHERITED(rt->desc(), SkBackingFit::kExact, rt->resourcePriv().isBudgeted())
36    , fTarget(std::move(rt))
37    , fFlags(fTarget->renderTargetPriv().flags())
38    , fLastDrawTarget(nullptr) {
39}
40
41GrRenderTargetProxy::~GrRenderTargetProxy() {
42    if (fLastDrawTarget) {
43        fLastDrawTarget->clearRT();
44    }
45    SkSafeUnref(fLastDrawTarget);
46}
47
48GrRenderTarget* GrRenderTargetProxy::instantiate(GrTextureProvider* texProvider) {
49    if (fTarget) {
50        return fTarget.get();
51    }
52
53    // TODO: it would be nice to not have to copy the desc here
54    GrSurfaceDesc desc = fDesc;
55    desc.fFlags |= GrSurfaceFlags::kRenderTarget_GrSurfaceFlag;
56
57    sk_sp<GrTexture> tex;
58    if (SkBackingFit::kApprox == fFit) {
59        tex.reset(texProvider->createApproxTexture(desc));
60    } else {
61        tex.reset(texProvider->createTexture(desc, fBudgeted));
62    }
63    if (!tex || !tex->asRenderTarget()) {
64        return nullptr;
65    }
66
67    fTarget = sk_ref_sp(tex->asRenderTarget());
68
69    // Check that our a priori computation matched the ultimate reality
70    SkASSERT(fFlags == fTarget->renderTargetPriv().flags());
71
72    return fTarget.get();
73}
74
75void GrRenderTargetProxy::setLastDrawTarget(GrDrawTarget* dt) {
76    if (fLastDrawTarget) {
77        // The non-MDB world never closes so we can't check this condition
78#ifdef ENABLE_MDB
79        SkASSERT(fLastDrawTarget->isClosed());
80#endif
81        fLastDrawTarget->clearRT();
82    }
83
84    SkRefCnt_SafeAssign(fLastDrawTarget, dt);
85}
86
87sk_sp<GrRenderTargetProxy> GrRenderTargetProxy::Make(const GrCaps& caps,
88                                                     const GrSurfaceDesc& desc,
89                                                     SkBackingFit fit,
90                                                     SkBudgeted budgeted) {
91    return sk_sp<GrRenderTargetProxy>(new GrRenderTargetProxy(caps, desc, fit, budgeted));
92}
93
94sk_sp<GrRenderTargetProxy> GrRenderTargetProxy::Make(const GrCaps& caps, sk_sp<GrRenderTarget> rt) {
95    return sk_sp<GrRenderTargetProxy>(new GrRenderTargetProxy(caps, rt));
96}
97
98