Home | History | Annotate | Download | only in gpu
      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 "GrGpuResourcePriv.h"
     12 #include "GrRenderTargetOpList.h"
     13 #include "GrRenderTargetPriv.h"
     14 #include "GrResourceProvider.h"
     15 #include "GrTextureRenderTargetProxy.h"
     16 #include "SkMathPriv.h"
     17 
     18 // Deferred version
     19 // TODO: we can probably munge the 'desc' in both the wrapped and deferred
     20 // cases to make the sampleConfig/numSamples stuff more rational.
     21 GrRenderTargetProxy::GrRenderTargetProxy(const GrCaps& caps, const GrSurfaceDesc& desc,
     22                                          SkBackingFit fit, SkBudgeted budgeted, uint32_t flags)
     23         : INHERITED(desc, fit, budgeted, flags)
     24         , fSampleCnt(desc.fSampleCnt)
     25         , fNeedsStencil(false)
     26         , fRenderTargetFlags(GrRenderTargetFlags::kNone) {
     27     // Since we know the newly created render target will be internal, we are able to precompute
     28     // what the flags will ultimately end up being.
     29     if (caps.usesMixedSamples() && fSampleCnt > 1) {
     30         fRenderTargetFlags |= GrRenderTargetFlags::kMixedSampled;
     31     }
     32     if (caps.maxWindowRectangles() > 0) {
     33         fRenderTargetFlags |= GrRenderTargetFlags::kWindowRectsSupport;
     34     }
     35 }
     36 
     37 // Lazy-callback version
     38 GrRenderTargetProxy::GrRenderTargetProxy(LazyInstantiateCallback&& callback,
     39                                          const GrSurfaceDesc& desc,
     40                                          SkBackingFit fit, SkBudgeted budgeted,
     41                                          uint32_t flags)
     42         : INHERITED(std::move(callback), desc, fit, budgeted, flags)
     43         , fSampleCnt(desc.fSampleCnt)
     44         , fNeedsStencil(false)
     45         , fRenderTargetFlags(GrRenderTargetFlags::kNone) {
     46     SkASSERT(SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags));
     47 }
     48 
     49 // Wrapped version
     50 GrRenderTargetProxy::GrRenderTargetProxy(sk_sp<GrSurface> surf, GrSurfaceOrigin origin)
     51         : INHERITED(std::move(surf), origin, SkBackingFit::kExact)
     52         , fSampleCnt(fTarget->asRenderTarget()->numStencilSamples())
     53         , fNeedsStencil(false)
     54         , fRenderTargetFlags(fTarget->asRenderTarget()->renderTargetPriv().flags()) {
     55 }
     56 
     57 int GrRenderTargetProxy::maxWindowRectangles(const GrCaps& caps) const {
     58     return (fRenderTargetFlags & GrRenderTargetFlags::kWindowRectsSupport)
     59                    ? caps.maxWindowRectangles()
     60                    : 0;
     61 }
     62 
     63 bool GrRenderTargetProxy::instantiate(GrResourceProvider* resourceProvider) {
     64     if (LazyState::kNot != this->lazyInstantiationState()) {
     65         return false;
     66     }
     67     static constexpr GrSurfaceFlags kFlags = kRenderTarget_GrSurfaceFlag;
     68 
     69     if (!this->instantiateImpl(resourceProvider, fSampleCnt, fNeedsStencil, kFlags,
     70                                GrMipMapped::kNo,
     71                                SkDestinationSurfaceColorMode::kLegacy, nullptr)) {
     72         return false;
     73     }
     74     SkASSERT(fTarget->asRenderTarget());
     75     SkASSERT(!fTarget->asTexture());
     76     // Check that our a priori computation matched the ultimate reality
     77     SkASSERT(fRenderTargetFlags == fTarget->asRenderTarget()->renderTargetPriv().flags());
     78 
     79     return true;
     80 }
     81 
     82 sk_sp<GrSurface> GrRenderTargetProxy::createSurface(GrResourceProvider* resourceProvider) const {
     83     static constexpr GrSurfaceFlags kFlags = kRenderTarget_GrSurfaceFlag;
     84 
     85     sk_sp<GrSurface> surface = this->createSurfaceImpl(resourceProvider, fSampleCnt, fNeedsStencil,
     86                                                        kFlags, GrMipMapped::kNo,
     87                                                        SkDestinationSurfaceColorMode::kLegacy);
     88     if (!surface) {
     89         return nullptr;
     90     }
     91     SkASSERT(surface->asRenderTarget());
     92     SkASSERT(!surface->asTexture());
     93     // Check that our a priori computation matched the ultimate reality
     94     SkASSERT(fRenderTargetFlags == surface->asRenderTarget()->renderTargetPriv().flags());
     95 
     96     return surface;
     97 }
     98 
     99 size_t GrRenderTargetProxy::onUninstantiatedGpuMemorySize() const {
    100     int colorSamplesPerPixel = this->numColorSamples();
    101     if (colorSamplesPerPixel > 1) {
    102         // Add one for the resolve buffer.
    103         ++colorSamplesPerPixel;
    104     }
    105 
    106     // TODO: do we have enough information to improve this worst case estimate?
    107     return GrSurface::ComputeSize(this->config(), this->width(), this->height(),
    108                                   colorSamplesPerPixel, GrMipMapped::kNo, !this->priv().isExact());
    109 }
    110 
    111 bool GrRenderTargetProxy::refsWrappedObjects() const {
    112     if (!fTarget) {
    113         return false;
    114     }
    115 
    116     return fTarget->resourcePriv().refsWrappedObjects();
    117 }
    118