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 "GrRenderTargetContext.h"
14 #include "GrGpu.h"
15 #include "GrRenderTargetOpList.h"
16 #include "GrRenderTargetPriv.h"
17 #include "GrStencilAttachment.h"
18 #include "GrStencilSettings.h"
19
GrRenderTarget(GrGpu * gpu,const GrSurfaceDesc & desc,Flags flags,GrStencilAttachment * stencil)20 GrRenderTarget::GrRenderTarget(GrGpu* gpu, const GrSurfaceDesc& desc, Flags flags,
21 GrStencilAttachment* stencil)
22 : INHERITED(gpu, desc)
23 , fStencilAttachment(stencil)
24 , fMultisampleSpecsID(0)
25 , fFlags(flags) {
26 SkASSERT(!(fFlags & Flags::kMixedSampled) || fDesc.fSampleCnt > 0);
27 SkASSERT(!(fFlags & Flags::kWindowRectsSupport) || gpu->caps()->maxWindowRectangles() > 0);
28 fResolveRect.setLargestInverted();
29 }
30
discard()31 void GrRenderTarget::discard() {
32 // go through context so that all necessary flushing occurs
33 GrContext* context = this->getContext();
34 if (!context) {
35 return;
36 }
37
38 sk_sp<GrRenderTargetContext> renderTargetContext(
39 context->contextPriv().makeWrappedRenderTargetContext(sk_ref_sp(this), nullptr));
40 if (!renderTargetContext) {
41 return;
42 }
43
44 renderTargetContext->discard();
45 }
46
flagAsNeedingResolve(const SkIRect * rect)47 void GrRenderTarget::flagAsNeedingResolve(const SkIRect* rect) {
48 if (kCanResolve_ResolveType == getResolveType()) {
49 if (rect) {
50 fResolveRect.join(*rect);
51 if (!fResolveRect.intersect(0, 0, this->width(), this->height())) {
52 fResolveRect.setEmpty();
53 }
54 } else {
55 fResolveRect.setLTRB(0, 0, this->width(), this->height());
56 }
57 }
58 }
59
overrideResolveRect(const SkIRect rect)60 void GrRenderTarget::overrideResolveRect(const SkIRect rect) {
61 fResolveRect = rect;
62 if (fResolveRect.isEmpty()) {
63 fResolveRect.setLargestInverted();
64 } else {
65 if (!fResolveRect.intersect(0, 0, this->width(), this->height())) {
66 fResolveRect.setLargestInverted();
67 }
68 }
69 }
70
onRelease()71 void GrRenderTarget::onRelease() {
72 SkSafeSetNull(fStencilAttachment);
73
74 INHERITED::onRelease();
75 }
76
onAbandon()77 void GrRenderTarget::onAbandon() {
78 SkSafeSetNull(fStencilAttachment);
79
80 // The contents of this renderTarget are gone/invalid. It isn't useful to point back
81 // the creating opList.
82 this->setLastOpList(nullptr);
83
84 INHERITED::onAbandon();
85 }
86
87 ///////////////////////////////////////////////////////////////////////////////
88
attachStencilAttachment(GrStencilAttachment * stencil)89 bool GrRenderTargetPriv::attachStencilAttachment(GrStencilAttachment* stencil) {
90 if (!stencil && !fRenderTarget->fStencilAttachment) {
91 // No need to do any work since we currently don't have a stencil attachment and
92 // we're not actually adding one.
93 return true;
94 }
95 fRenderTarget->fStencilAttachment = stencil;
96 if (!fRenderTarget->completeStencilAttachment()) {
97 SkSafeSetNull(fRenderTarget->fStencilAttachment);
98 return false;
99 }
100 return true;
101 }
102
numStencilBits() const103 int GrRenderTargetPriv::numStencilBits() const {
104 SkASSERT(this->getStencilAttachment());
105 return this->getStencilAttachment()->bits();
106 }
107
108 const GrGpu::MultisampleSpecs&
getMultisampleSpecs(const GrPipeline & pipeline) const109 GrRenderTargetPriv::getMultisampleSpecs(const GrPipeline& pipeline) const {
110 SkASSERT(fRenderTarget == pipeline.getRenderTarget()); // TODO: remove RT from pipeline.
111 GrGpu* gpu = fRenderTarget->getGpu();
112 if (auto id = fRenderTarget->fMultisampleSpecsID) {
113 SkASSERT(gpu->queryMultisampleSpecs(pipeline).fUniqueID == id);
114 return gpu->getMultisampleSpecs(id);
115 }
116 const GrGpu::MultisampleSpecs& specs = gpu->queryMultisampleSpecs(pipeline);
117 fRenderTarget->fMultisampleSpecsID = specs.fUniqueID;
118 return specs;
119 }
120
121