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 #ifndef GrGLRenderTarget_DEFINED
10 #define GrGLRenderTarget_DEFINED
11 
12 #include "GrGLIRect.h"
13 #include "GrRenderTarget.h"
14 #include "SkScalar.h"
15 
16 class GrGLGpu;
17 
18 class GrGLRenderTarget : public GrRenderTarget {
19 public:
20     // set fTexFBOID to this value to indicate that it is multisampled but
21     // Gr doesn't know how to resolve it.
22     enum { kUnresolvableFBOID = 0 };
23 
24     struct IDDesc {
25         GrGLuint                    fRTFBOID;
26         GrGLuint                    fTexFBOID;
27         GrGLuint                    fMSColorRenderbufferID;
28         GrGpuResource::LifeCycle    fLifeCycle;
29     };
30 
31     GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&);
32 
setViewport(const GrGLIRect & rect)33     void setViewport(const GrGLIRect& rect) { fViewport = rect; }
getViewport()34     const GrGLIRect& getViewport() const { return fViewport; }
35 
36     // The following two functions return the same ID when a
37     // texture/render target is multisampled, and different IDs when
38     // it is.
39     // FBO ID used to render into
renderFBOID()40     GrGLuint renderFBOID() const { return fRTFBOID; }
41     // FBO ID that has texture ID attached.
textureFBOID()42     GrGLuint textureFBOID() const { return fTexFBOID; }
43 
44     // override of GrRenderTarget
getResolveType()45     ResolveType getResolveType() const override {
46         if (!this->isMultisampled() ||
47             fRTFBOID == fTexFBOID) {
48             // catches FBO 0 and non MSAA case
49             return kAutoResolves_ResolveType;
50         } else if (kUnresolvableFBOID == fTexFBOID) {
51             return kCantResolve_ResolveType;
52         } else {
53             return kCanResolve_ResolveType;
54         }
55     }
56 
57     /** When we don't own the FBO ID we don't attempt to modify its attachments. */
canAttemptStencilAttachment()58     bool canAttemptStencilAttachment() const override { return !fIsWrapped; }
59 
60 protected:
61     // The public constructor registers this object with the cache. However, only the most derived
62     // class should register with the cache. This constructor does not do the registration and
63     // rather moves that burden onto the derived class.
64     enum Derived { kDerived };
65     GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, Derived);
66 
67     void init(const GrSurfaceDesc&, const IDDesc&);
68 
69     void onAbandon() override;
70     void onRelease() override;
71 
72     // In protected because subclass GrGLTextureRenderTarget calls this version.
73     size_t onGpuMemorySize() const override;
74 
75 private:
76     GrGLuint      fRTFBOID;
77     GrGLuint      fTexFBOID;
78     GrGLuint      fMSColorRenderbufferID;
79 
80     // We track this separately from GrGpuResource because this may be both a texture and a render
81     // target, and the texture may be wrapped while the render target is not.
82     bool fIsWrapped;
83 
84     // when we switch to this render target we want to set the viewport to
85     // only render to content area (as opposed to the whole allocation) and
86     // we want the rendering to be at top left (GL has origin in bottom left)
87     GrGLIRect fViewport;
88 
89     // onGpuMemorySize() needs to know the VRAM footprint of the FBO(s). However, abandon and
90     // release zero out the IDs and the cache needs to know the size even after those actions.
91     size_t fGpuMemorySize;
92 
93     typedef GrRenderTarget INHERITED;
94 };
95 
96 #endif
97