1 /*
2 * Copyright 2011 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
9 #include "GrRenderTarget.h"
10
11 #include "GrContext.h"
12 #include "GrContextPriv.h"
13 #include "GrDrawContext.h"
14 #include "GrDrawTarget.h"
15 #include "GrGpu.h"
16 #include "GrRenderTargetPriv.h"
17 #include "GrStencilAttachment.h"
18
GrRenderTarget(GrGpu * gpu,const GrSurfaceDesc & desc,Flags flags,GrStencilAttachment * stencil)19 GrRenderTarget::GrRenderTarget(GrGpu* gpu, const GrSurfaceDesc& desc, Flags flags,
20 GrStencilAttachment* stencil)
21 : INHERITED(gpu, desc)
22 , fStencilAttachment(stencil)
23 , fMultisampleSpecsID(0)
24 , fFlags(flags)
25 , fLastDrawTarget(nullptr) {
26 SkASSERT(!(fFlags & Flags::kMixedSampled) || fDesc.fSampleCnt > 0);
27 SkASSERT(!(fFlags & Flags::kWindowRectsSupport) || gpu->caps()->maxWindowRectangles() > 0);
28 fResolveRect.setLargestInverted();
29 }
30
~GrRenderTarget()31 GrRenderTarget::~GrRenderTarget() {
32 if (fLastDrawTarget) {
33 fLastDrawTarget->clearRT();
34 }
35 SkSafeUnref(fLastDrawTarget);
36 }
37
discard()38 void GrRenderTarget::discard() {
39 // go through context so that all necessary flushing occurs
40 GrContext* context = this->getContext();
41 if (!context) {
42 return;
43 }
44
45 sk_sp<GrDrawContext> drawContext(context->contextPriv().makeWrappedDrawContext(sk_ref_sp(this),
46 nullptr));
47 if (!drawContext) {
48 return;
49 }
50
51 drawContext->discard();
52 }
53
flagAsNeedingResolve(const SkIRect * rect)54 void GrRenderTarget::flagAsNeedingResolve(const SkIRect* rect) {
55 if (kCanResolve_ResolveType == getResolveType()) {
56 if (rect) {
57 fResolveRect.join(*rect);
58 if (!fResolveRect.intersect(0, 0, this->width(), this->height())) {
59 fResolveRect.setEmpty();
60 }
61 } else {
62 fResolveRect.setLTRB(0, 0, this->width(), this->height());
63 }
64 }
65 }
66
overrideResolveRect(const SkIRect rect)67 void GrRenderTarget::overrideResolveRect(const SkIRect rect) {
68 fResolveRect = rect;
69 if (fResolveRect.isEmpty()) {
70 fResolveRect.setLargestInverted();
71 } else {
72 if (!fResolveRect.intersect(0, 0, this->width(), this->height())) {
73 fResolveRect.setLargestInverted();
74 }
75 }
76 }
77
onRelease()78 void GrRenderTarget::onRelease() {
79 SkSafeSetNull(fStencilAttachment);
80
81 INHERITED::onRelease();
82 }
83
onAbandon()84 void GrRenderTarget::onAbandon() {
85 SkSafeSetNull(fStencilAttachment);
86
87 // The contents of this renderTarget are gone/invalid. It isn't useful to point back
88 // the creating drawTarget.
89 this->setLastDrawTarget(nullptr);
90
91 INHERITED::onAbandon();
92 }
93
setLastDrawTarget(GrDrawTarget * dt)94 void GrRenderTarget::setLastDrawTarget(GrDrawTarget* dt) {
95 if (fLastDrawTarget) {
96 // The non-MDB world never closes so we can't check this condition
97 #ifdef ENABLE_MDB
98 SkASSERT(fLastDrawTarget->isClosed());
99 #endif
100 fLastDrawTarget->clearRT();
101 }
102
103 SkRefCnt_SafeAssign(fLastDrawTarget, dt);
104 }
105
106 ///////////////////////////////////////////////////////////////////////////////
107
attachStencilAttachment(GrStencilAttachment * stencil)108 bool GrRenderTargetPriv::attachStencilAttachment(GrStencilAttachment* stencil) {
109 if (!stencil && !fRenderTarget->fStencilAttachment) {
110 // No need to do any work since we currently don't have a stencil attachment and
111 // we're not acctually adding one.
112 return true;
113 }
114 fRenderTarget->fStencilAttachment = stencil;
115 if (!fRenderTarget->completeStencilAttachment()) {
116 SkSafeSetNull(fRenderTarget->fStencilAttachment);
117 return false;
118 }
119 return true;
120 }
121
numStencilBits() const122 int GrRenderTargetPriv::numStencilBits() const {
123 return fRenderTarget->fStencilAttachment ? fRenderTarget->fStencilAttachment->bits() : 0;
124 }
125
126 const GrGpu::MultisampleSpecs&
getMultisampleSpecs(const GrStencilSettings & stencil) const127 GrRenderTargetPriv::getMultisampleSpecs(const GrStencilSettings& stencil) const {
128 return fRenderTarget->getGpu()->getMultisampleSpecs(fRenderTarget, stencil);
129 }
130
maxWindowRectangles() const131 int GrRenderTargetPriv::maxWindowRectangles() const {
132 return (this->flags() & Flags::kWindowRectsSupport) ?
133 fRenderTarget->getGpu()->caps()->maxWindowRectangles() : 0;
134 }
135