Home | History | Annotate | Download | only in gpu
      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 
     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 
     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 
     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 
     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 
     71 void GrRenderTarget::onRelease() {
     72     SkSafeSetNull(fStencilAttachment);
     73 
     74     INHERITED::onRelease();
     75 }
     76 
     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 
     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 
    103 int GrRenderTargetPriv::numStencilBits() const {
    104     SkASSERT(this->getStencilAttachment());
    105     return this->getStencilAttachment()->bits();
    106 }
    107 
    108 const GrGpu::MultisampleSpecs&
    109 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