/* * Copyright 2011 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef GrGLRenderTarget_DEFINED #define GrGLRenderTarget_DEFINED #include "GrGLIRect.h" #include "GrRenderTarget.h" #include "SkScalar.h" class GrGLGpu; class GrGLStencilAttachment; class GrGLRenderTarget : public GrRenderTarget { public: // set fTexFBOID to this value to indicate that it is multisampled but // Gr doesn't know how to resolve it. enum { kUnresolvableFBOID = 0 }; struct IDDesc { GrGLuint fRTFBOID; GrGLuint fTexFBOID; GrGLuint fMSColorRenderbufferID; GrGpuResource::LifeCycle fLifeCycle; GrRenderTarget::SampleConfig fSampleConfig; }; static GrGLRenderTarget* CreateWrapped(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, int stencilBits); void setViewport(const GrGLIRect& rect) { fViewport = rect; } const GrGLIRect& getViewport() const { return fViewport; } // The following two functions return the same ID when a // texture/render target is multisampled, and different IDs when // it is. // FBO ID used to render into GrGLuint renderFBOID() const { return fRTFBOID; } // FBO ID that has texture ID attached. GrGLuint textureFBOID() const { return fTexFBOID; } // override of GrRenderTarget ResolveType getResolveType() const override { if (!this->isUnifiedMultisampled() || fRTFBOID == fTexFBOID) { // catches FBO 0 and non MSAA case return kAutoResolves_ResolveType; } else if (kUnresolvableFBOID == fTexFBOID) { return kCantResolve_ResolveType; } else { return kCanResolve_ResolveType; } } GrBackendObject getRenderTargetHandle() const override { return fRTFBOID; } /** When we don't own the FBO ID we don't attempt to modify its attachments. */ bool canAttemptStencilAttachment() const override { return kCached_LifeCycle == fRTLifecycle || kUncached_LifeCycle == fRTLifecycle; } // GrGLRenderTarget overrides dumpMemoryStatistics so it can log its texture and renderbuffer // components seperately. void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const override; protected: // The public constructor registers this object with the cache. However, only the most derived // class should register with the cache. This constructor does not do the registration and // rather moves that burden onto the derived class. enum Derived { kDerived }; GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, Derived); void init(const GrSurfaceDesc&, const IDDesc&); void onAbandon() override; void onRelease() override; // In protected because subclass GrGLTextureRenderTarget calls this version. size_t onGpuMemorySize() const override; private: // This ctor is used only for creating wrapped render targets and is only called for the static // create function CreateWrapped(...). GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, GrGLStencilAttachment*); GrGLGpu* getGLGpu() const; bool completeStencilAttachment() override; // The total size of the resource (including all pixels) for a single sample. size_t totalBytesPerSample() const; int msaaSamples() const; // The number total number of samples, including both MSAA and resolve texture samples. int totalSamples() const; GrGLuint fRTFBOID; GrGLuint fTexFBOID; GrGLuint fMSColorRenderbufferID; // We track this separately from GrGpuResource because this may be both a texture and a render // target, and the texture may be wrapped while the render target is not. LifeCycle fRTLifecycle; // when we switch to this render target we want to set the viewport to // only render to content area (as opposed to the whole allocation) and // we want the rendering to be at top left (GL has origin in bottom left) GrGLIRect fViewport; // onGpuMemorySize() needs to know the VRAM footprint of the FBO(s). However, abandon and // release zero out the IDs and the cache needs to know the size even after those actions. size_t fGpuMemorySize; typedef GrRenderTarget INHERITED; }; #endif