blob: 3d6587fefe398505dc69d570104b1935b97c001f [file] [log] [blame]
robertphillips76948d42016-05-04 12:47:41 -07001/*
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
csmartdaltonf9635992016-08-10 11:09:07 -070010#include "GrCaps.h"
robertphillips76948d42016-05-04 12:47:41 -070011#include "GrDrawTarget.h"
12#include "GrGpuResourcePriv.h"
robertphillips76948d42016-05-04 12:47:41 -070013
csmartdaltonf9635992016-08-10 11:09:07 -070014// 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)
robertphillips76948d42016-05-04 12:47:41 -070035 : INHERITED(rt->desc(), SkBackingFit::kExact, rt->resourcePriv().isBudgeted())
36 , fTarget(std::move(rt))
csmartdaltonf9635992016-08-10 11:09:07 -070037 , fFlags(fTarget->renderTargetPriv().flags())
robertphillips76948d42016-05-04 12:47:41 -070038 , 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
csmartdaltonf9635992016-08-10 11:09:07 -070070 SkASSERT(fFlags == fTarget->renderTargetPriv().flags());
robertphillips76948d42016-05-04 12:47:41 -070071
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
csmartdaltonf9635992016-08-10 11:09:07 -070094sk_sp<GrRenderTargetProxy> GrRenderTargetProxy::Make(const GrCaps& caps, sk_sp<GrRenderTarget> rt) {
95 return sk_sp<GrRenderTargetProxy>(new GrRenderTargetProxy(caps, rt));
robertphillips76948d42016-05-04 12:47:41 -070096}
97